libcanvas/Canvas{Ex,Im}portStore.py: cleanup.

assets/tools/MiRCARTReduce.py: fixed (for spoke.)
assets/tools/{MiRCARTTo{Ansi,PngFile},SAUCETo{Ansi,MiRCART}}.py: updated.
lib{canvas/Canvas,gui/Gui{CanvasInterface,Frame}}.py: updated.
lib{{canvas/Canvas{Backend,Journal},Colours},tools/ToolRect}.py: minor cleanup.
roar.py: updated.
This commit is contained in:
Lucio Andrés Illanes Albornoz 2019-09-06 10:29:45 +02:00
parent bb4ba3ae46
commit 34d9df756b
15 changed files with 440 additions and 609 deletions

View File

@ -12,8 +12,7 @@ from CanvasImportStore import CanvasImportStore
import sys import sys
def reduce(inPathName): def reduce(inPathName):
canvasStore = CanvasImportStore(inPathName) canvasStore = CanvasImportStore(inPathName); inMap = canvasStore.outMap.copy();
inMap = canvasStore.outMap.copy(); del canvasStore;
with open(inPathName, "w+") as outFile: with open(inPathName, "w+") as outFile:
for inCurRow in range(len(inMap)): for inCurRow in range(len(inMap)):
lastAttribs, lastColours = CanvasImportStore._CellState.CS_NONE, None lastAttribs, lastColours = CanvasImportStore._CellState.CS_NONE, None
@ -25,15 +24,21 @@ def reduce(inPathName):
if inCurCell[2] & CanvasImportStore._CellState.CS_UNDERLINE: if inCurCell[2] & CanvasImportStore._CellState.CS_UNDERLINE:
print("\u001f", end="", file=outFile) print("\u001f", end="", file=outFile)
lastAttribs = inCurCell[2] lastAttribs = inCurCell[2]
if lastColours == None \ if lastColours == None \
or (lastColours[0] != inCurCell[:2][0] \ or (lastColours[0] != inCurCell[:2][0] \
and lastColours[1] != inCurCell[:2][1]): and lastColours[1] != inCurCell[:2][1]):
print("\u0003{:d},{:d}{}".format(*inCurCell[:2], inCurCell[3]), end="", file=outFile) if (inCurCell[3] in set("0123456789")) and (inCurCell[1] < 10):
print("\u0003{:d},{:02d}{}".format(*inCurCell[:2], inCurCell[3]), end="", file=outFile)
else:
print("\u0003{:d},{:d}{}".format(*inCurCell[:2], inCurCell[3]), end="", file=outFile)
lastColours = inCurCell[:2] lastColours = inCurCell[:2]
elif lastColours[1] == inCurCell[:2][1] \ elif (lastColours[1] == inCurCell[:2][1]) \
and lastColours[0] != inCurCell[:2][0]: and (lastColours[0] != inCurCell[:2][0]):
print("\u0003{:d}{}".format(inCurCell[:2][0], inCurCell[3]), end="", file=outFile) if (inCurCell[3] in set("0123456789")) and (inCurCell[0] < 10):
lastColours[0] = inCurCell[:2][0] print("\u0003{:02d}{}".format(inCurCell[0], inCurCell[3]), end="", file=outFile)
else:
print("\u0003{:d}{}".format(inCurCell[0], inCurCell[3]), end="", file=outFile)
lastColours[0] = inCurCell[0]
else: else:
print(inCurCell[3], end="", file=outFile) print(inCurCell[3], end="", file=outFile)
print("\n", end="", file=outFile) print("\n", end="", file=outFile)

View File

@ -18,9 +18,12 @@ def main(*argv):
print("usage: {} <MiRCART input file pathname>".format(sys.argv[0]), file=sys.stderr) print("usage: {} <MiRCART input file pathname>".format(sys.argv[0]), file=sys.stderr)
else: else:
canvasImportStore = CanvasImportStore() canvasImportStore = CanvasImportStore()
canvasImportStore.importAnsiFile(argv[1]) rc, error = canvasImportStore.importAnsiFile(argv[1])
canvasExportStore = CanvasExportStore() if rc:
canvasExportStore.exportAnsiFile(canvasImportStore.outMap, canvasImportStore.inSize, sys.stdout) canvasExportStore = CanvasExportStore()
canvasExportStore.exportAnsiFile(canvasImportStore.outMap, canvasImportStore.inSize, sys.stdout)
else
print("error: {}".format(error), file=sys.stderr)
if __name__ == "__main__": if __name__ == "__main__":
main(*sys.argv) main(*sys.argv)

View File

@ -27,9 +27,12 @@ def main(*argv):
optdict["-s"] = 11 if not "-s" in optdict else int(optdict["-s"]) optdict["-s"] = 11 if not "-s" in optdict else int(optdict["-s"])
for inFile in argv: for inFile in argv:
canvasImportStore = CanvasImportStore() canvasImportStore = CanvasImportStore()
canvasImportStore.importTextFile(inFile) rc, error = canvasImportStore.importTextFile(inFile)
canvasExportStore = CanvasExportStore() if rc:
canvasExportStore.exportPngFile(canvasImportStore.outMap, os.path.splitext(inFile)[0] + ".png", optdict["-f"], optdict["-s"]) canvasExportStore = CanvasExportStore()
canvasExportStore.exportPngFile(canvasImportStore.outMap, optdict["-f"], optdict["-s"], os.path.splitext(inFile)[0] + ".png")
else:
print("error: {}".format(error), file=sys.stderr)
if __name__ == "__main__": if __name__ == "__main__":
main(*sys.argv) main(*sys.argv)

View File

@ -18,10 +18,13 @@ def main(*argv):
print("usage: {} <SAUCE input file pathname> <ANSI output file pathname>".format(sys.argv[0]), file=sys.stderr) print("usage: {} <SAUCE input file pathname> <ANSI output file pathname>".format(sys.argv[0]), file=sys.stderr)
else: else:
canvasImportStore = CanvasImportStore() canvasImportStore = CanvasImportStore()
canvasImportStore.importSauceFile(argv[1]) rc, error = canvasImportStore.importSauceFile(argv[1])
canvasExportStore = CanvasExportStore() if rc:
with open(argv[2], "w", encoding="utf-8") as outFile: canvasExportStore = CanvasExportStore()
canvasExportStore.exportAnsiFile(canvasImportStore.outMap, canvasImportStore.inSize, outFile) with open(argv[2], "w", encoding="utf-8") as outFile:
canvasExportStore.exportAnsiFile(canvasImportStore.outMap, canvasImportStore.inSize, outFile)
else:
print("error: {}".format(error), file=sys.stderr)
if __name__ == "__main__": if __name__ == "__main__":
main(*sys.argv) main(*sys.argv)

View File

@ -18,10 +18,13 @@ def main(*argv):
print("usage: {} <SAUCE input file pathname> <mIRC art output file pathname>".format(sys.argv[0]), file=sys.stderr) print("usage: {} <SAUCE input file pathname> <mIRC art output file pathname>".format(sys.argv[0]), file=sys.stderr)
else: else:
canvasImportStore = CanvasImportStore() canvasImportStore = CanvasImportStore()
canvasImportStore.importSauceFile(argv[1]) rc, error = canvasImportStore.importSauceFile(argv[1])
canvasExportStore = CanvasExportStore() if rc:
with open(argv[2], "w", encoding="utf-8") as outFile: canvasExportStore = CanvasExportStore()
canvasExportStore.exportTextFile(canvasImportStore.outMap, canvasImportStore.inSize, outFile) with open(argv[2], "w", encoding="utf-8") as outFile:
canvasExportStore.exportTextFile(canvasImportStore.outMap, canvasImportStore.inSize, outFile)
else:
print("error: {}".format(error), file=sys.stderr)
if __name__ == "__main__": if __name__ == "__main__":
main(*sys.argv) main(*sys.argv)

View File

@ -43,7 +43,7 @@ class Canvas(wx.Panel):
if commitUndo: if commitUndo:
if not self._canvasDirty: if not self._canvasDirty:
self.canvasJournal.pushDeltas([], []); self._canvasDirty = True; self.canvasJournal.pushDeltas([], []); self._canvasDirty = True;
self.canvasJournal.updateCurrentDeltas(patchDelta, patch) self.canvasJournal.updateCurrentDeltas(patch, patchDelta)
self._commitPatch(patch) self._commitPatch(patch)
# }}} # }}}
@ -90,7 +90,7 @@ class Canvas(wx.Panel):
# }}} # }}}
# {{{ onPanelPaint(self, event): XXX # {{{ onPanelPaint(self, event): XXX
def onPanelPaint(self, event): def onPanelPaint(self, event):
self.canvasBackend.onPanelPaintEvent(self, event) self.canvasBackend.onPanelPaintEvent(event, self)
# }}} # }}}
# {{{ onStoreUpdate(self, newCanvasSize, newCanvas=None): XXX # {{{ onStoreUpdate(self, newCanvasSize, newCanvas=None): XXX
def onStoreUpdate(self, newCanvasSize, newCanvas=None): def onStoreUpdate(self, newCanvasSize, newCanvas=None):
@ -129,7 +129,7 @@ class Canvas(wx.Panel):
undoPatches, redoPatches = ["resize", *oldCanvasSize], ["resize", *newCanvasSize] undoPatches, redoPatches = ["resize", *oldCanvasSize], ["resize", *newCanvasSize]
if not self._canvasDirty: if not self._canvasDirty:
self.canvasJournal.pushDeltas([], []); self._canvasDirty = True; self.canvasJournal.pushDeltas([], []); self._canvasDirty = True;
self.canvasJournal.updateCurrentDeltas(undoPatches, redoPatches) self.canvasJournal.updateCurrentDeltas(redoPatches, undoPatches)
if deltaCanvasSize[0] < 0: if deltaCanvasSize[0] < 0:
for numRow in range(oldCanvasSize[1]): for numRow in range(oldCanvasSize[1]):
@ -137,7 +137,7 @@ class Canvas(wx.Panel):
for numCol in range((oldCanvasSize[0] + deltaCanvasSize[0]), oldCanvasSize[0]): for numCol in range((oldCanvasSize[0] + deltaCanvasSize[0]), oldCanvasSize[0]):
if not self._canvasDirty: if not self._canvasDirty:
self.canvasJournal.pushDeltas([], []); self._canvasDirty = True; self.canvasJournal.pushDeltas([], []); self._canvasDirty = True;
self.canvasJournal.updateCurrentDeltas([numCol, numRow, *self.canvasMap[numRow][numCol]], [numCol, numRow, 1, 1, 0, " "]) self.canvasJournal.updateCurrentDeltas([numCol, numRow, 1, 1, 0, " "], [numCol, numRow, *self.canvasMap[numRow][numCol]])
del self.canvasMap[numRow][-1:(deltaCanvasSize[0]-1):-1] del self.canvasMap[numRow][-1:(deltaCanvasSize[0]-1):-1]
else: else:
for numRow in range(oldCanvasSize[1]): for numRow in range(oldCanvasSize[1]):
@ -150,7 +150,7 @@ class Canvas(wx.Panel):
for numCol in range(oldCanvasSize[0] + deltaCanvasSize[0]): for numCol in range(oldCanvasSize[0] + deltaCanvasSize[0]):
if not self._canvasDirty: if not self._canvasDirty:
self.canvasJournal.pushDeltas([], []); self._canvasDirty = True; self.canvasJournal.pushDeltas([], []); self._canvasDirty = True;
self.canvasJournal.updateCurrentDeltas([numCol, numRow, *self.canvasMap[numRow][numCol]], [numCol, numRow, 1, 1, 0, " "]) self.canvasJournal.updateCurrentDeltas([numCol, numRow, 1, 1, 0, " "], [numCol, numRow, *self.canvasMap[numRow][numCol]])
del self.canvasMap[-1:(deltaCanvasSize[1]-1):-1] del self.canvasMap[-1:(deltaCanvasSize[1]-1):-1]
else: else:
for numNewRow in range(oldCanvasSize[1], newCanvasSize[1]): for numNewRow in range(oldCanvasSize[1], newCanvasSize[1]):
@ -182,7 +182,7 @@ class Canvas(wx.Panel):
self.canvasBackend = CanvasBackend(defaultCanvasSize, defaultCellSize) self.canvasBackend = CanvasBackend(defaultCanvasSize, defaultCellSize)
self.canvasJournal = CanvasJournal() self.canvasJournal = CanvasJournal()
self.canvasExportStore = CanvasExportStore() self.canvasExportStore = CanvasExportStore()
self.canvasImportStore = CanvasImportStore(parentCanvas=self) self.canvasImportStore = CanvasImportStore()
self.canvasInterface = canvasInterface(self, parentFrame) self.canvasInterface = canvasInterface(self, parentFrame)
# Bind event handlers # Bind event handlers

View File

@ -13,81 +13,59 @@ class CanvasBackend():
# {{{ _drawBrushPatch(self, eventDc, patch): XXX # {{{ _drawBrushPatch(self, eventDc, patch): XXX
def _drawBrushPatch(self, eventDc, patch): def _drawBrushPatch(self, eventDc, patch):
absPoint = self._xlatePoint(patch) absPoint = self._xlatePoint(patch)
brushFg = self._brushes[patch[3]] brushBg, brushFg, pen = self._brushes[patch[2]], self._brushes[patch[3]], self._pens[patch[3]]
brushBg = self._brushes[patch[2]]
pen = self._pens[patch[3]]
self._setBrushDc(brushBg, brushFg, eventDc, pen) self._setBrushDc(brushBg, brushFg, eventDc, pen)
eventDc.DrawRectangle(*absPoint, *self.cellSize) eventDc.DrawRectangle(*absPoint, *self.cellSize)
# }}} # }}}
# {{{ _drawCharPatch(self, eventDc, patch): XXX # {{{ _drawCharPatch(self, eventDc, patch): XXX
def _drawCharPatch(self, eventDc, patch): def _drawCharPatch(self, eventDc, patch):
absPoint = self._xlatePoint(patch) absPoint, fontBitmap = self._xlatePoint(patch), wx.Bitmap(*self.cellSize)
brushFg = self._brushes[patch[2]] brushBg, brushFg, pen = self._brushes[patch[3]], self._brushes[patch[2]], self._pens[patch[3]]
brushBg = self._brushes[patch[3]]
pen = self._pens[patch[3]]
fontBitmap = wx.Bitmap(*self.cellSize)
fontDc = wx.MemoryDC(); fontDc.SelectObject(fontBitmap); fontDc = wx.MemoryDC(); fontDc.SelectObject(fontBitmap);
fontDc.SetTextForeground(wx.Colour(Colours[patch[2]][0:4])) fontDc.SetTextForeground(wx.Colour(Colours[patch[2]][:4]))
fontDc.SetTextBackground(wx.Colour(Colours[patch[3]][0:4])) fontDc.SetTextBackground(wx.Colour(Colours[patch[3]][:4]))
fontDc.SetBrush(brushBg); fontDc.SetBackground(brushBg); fontDc.SetPen(pen); fontDc.SetBrush(brushBg); fontDc.SetBackground(brushBg); fontDc.SetPen(pen);
fontDc.SetFont(self._font) fontDc.SetFont(self._font)
fontDc.DrawRectangle(0, 0, *self.cellSize) fontDc.DrawRectangle(0, 0, *self.cellSize); fontDc.DrawText(patch[5], 0, 0);
fontDc.DrawText(patch[5], 0, 0)
eventDc.Blit(*absPoint, *self.cellSize, fontDc, 0, 0) eventDc.Blit(*absPoint, *self.cellSize, fontDc, 0, 0)
# }}} # }}}
# {{{ _finiBrushesAndPens(self): XXX # {{{ _finiBrushesAndPens(self): XXX
def _finiBrushesAndPens(self): def _finiBrushesAndPens(self):
for brush in self._brushes or []: [brush.Destroy() for brush in self._brushes or []]
brush.Destroy() [pen.Destroy() for pen in self._pens or []]
self._brushes = None self._brushes, self._lastBrushBg, self._lastBrushFg, self._lastPen, self._pens = None, None, None, None, None
for pen in self._pens or []:
pen.Destroy()
self._pens = None
self._lastBrushBg = self._lastBrushFg = self._lastPen = None;
# }}} # }}}
# {{{ _initBrushesAndPens(self): XXX # {{{ _initBrushesAndPens(self): XXX
def _initBrushesAndPens(self): def _initBrushesAndPens(self):
self._brushes = [None for x in range(len(Colours))] self._brushes, self._pens = [None for x in range(len(Colours))], [None for x in range(len(Colours))]
self._pens = [None for x in range(len(Colours))]
for mircColour in range(len(Colours)): for mircColour in range(len(Colours)):
self._brushes[mircColour] = wx.Brush( \ self._brushes[mircColour] = wx.Brush(wx.Colour(Colours[mircColour][:4]), wx.BRUSHSTYLE_SOLID)
wx.Colour(Colours[mircColour][0:4]), wx.BRUSHSTYLE_SOLID) self._pens[mircColour] = wx.Pen(wx.Colour(Colours[mircColour][:4]), 1)
self._pens[mircColour] = wx.Pen( \ self._lastBrushBg, self._lastBrushFg, self._lastPen = None, None, None
wx.Colour(Colours[mircColour][0:4]), 1)
self._lastBrushBg = self._lastBrushFg = self._lastPen = None;
# }}} # }}}
# {{{ _setBrushDc(self, brushBg, brushFg, dc, pen): XXX # {{{ _setBrushDc(self, brushBg, brushFg, dc, pen): XXX
def _setBrushDc(self, brushBg, brushFg, dc, pen): def _setBrushDc(self, brushBg, brushFg, dc, pen):
if self._lastBrushBg != brushBg: if self._lastBrushBg != brushBg:
dc.SetBackground(brushBg) dc.SetBackground(brushBg); self._lastBrushBg = brushBg;
self._lastBrushBg = brushBg
if self._lastBrushFg != brushFg: if self._lastBrushFg != brushFg:
dc.SetBrush(brushFg) dc.SetBrush(brushFg); self._lastBrushFg = brushFg;
self._lastBrushFg = brushFg
if self._lastPen != pen: if self._lastPen != pen:
dc.SetPen(pen) dc.SetPen(pen); self._lastPen = pen;
self._lastPen = pen
# }}} # }}}
# {{{ _xlatePoint(self, patch): XXX # {{{ _xlatePoint(self, patch): XXX
def _xlatePoint(self, patch): def _xlatePoint(self, patch):
return [a * b for a, b in zip(patch[0:2], self.cellSize)] return [a * b for a, b in zip(patch[:2], self.cellSize)]
# }}} # }}}
# {{{ drawCursorMaskWithJournal(self, canvasJournal, eventDc): XXX # {{{ drawCursorMaskWithJournal(self, canvasJournal, eventDc): XXX
def drawCursorMaskWithJournal(self, canvasJournal, eventDc): def drawCursorMaskWithJournal(self, canvasJournal, eventDc):
for patch in canvasJournal.popCursor(): [self.drawPatch(eventDc, patch) for patch in canvasJournal.popCursor()]
self.drawPatch(eventDc, patch)
# }}} # }}}
# {{{ drawPatch(self, eventDc, patch): XXX # {{{ drawPatch(self, eventDc, patch): XXX
def drawPatch(self, eventDc, patch): def drawPatch(self, eventDc, patch):
if patch[0] < self.canvasSize[0] \ if ((patch[0] >= 0) and (patch[0] < self.canvasSize[0])) \
and patch[0] >= 0 \ and ((patch[1] >= 0) and (patch[1] < self.canvasSize[1])):
and patch[1] < self.canvasSize[1] \ self._drawBrushPatch(eventDc, patch) if patch[5] == " " else self._drawCharPatch(eventDc, patch)
and patch[1] >= 0:
if patch[5] == " ":
self._drawBrushPatch(eventDc, patch)
else:
self._drawCharPatch(eventDc, patch)
return True return True
else: else:
return False return False
@ -95,11 +73,11 @@ class CanvasBackend():
# {{{ getDeviceContext(self, parentWindow): XXX # {{{ getDeviceContext(self, parentWindow): XXX
def getDeviceContext(self, parentWindow): def getDeviceContext(self, parentWindow):
eventDc = wx.BufferedDC(wx.ClientDC(parentWindow), self.canvasBitmap) eventDc = wx.BufferedDC(wx.ClientDC(parentWindow), self.canvasBitmap)
self._lastBrushBg = self._lastBrushFg = self._lastPen = None; self._lastBrushBg, self._lastBrushFg, self._lastPen = None, None, None
return eventDc return eventDc
# }}} # }}}
# {{{ onPanelPaintEvent(self, panelWindow, panelEvent): XXX # {{{ onPanelPaintEvent(self, panelEvent, panelWindow): XXX
def onPanelPaintEvent(self, panelWindow, panelEvent): def onPanelPaintEvent(self, panelEvent, panelWindow):
if self.canvasBitmap != None: if self.canvasBitmap != None:
eventDc = wx.BufferedPaintDC(panelWindow, self.canvasBitmap) eventDc = wx.BufferedPaintDC(panelWindow, self.canvasBitmap)
# }}} # }}}
@ -113,27 +91,19 @@ class CanvasBackend():
if self.canvasBitmap == None: if self.canvasBitmap == None:
self.canvasBitmap = wx.Bitmap(winSize) self.canvasBitmap = wx.Bitmap(winSize)
else: else:
oldDc = wx.MemoryDC() oldDc = wx.MemoryDC(); oldDc.SelectObject(self.canvasBitmap);
oldDc.SelectObject(self.canvasBitmap) newDc = wx.MemoryDC(); newBitmap = wx.Bitmap(winSize); newDc.SelectObject(newBitmap);
newDc = wx.MemoryDC()
newBitmap = wx.Bitmap(winSize)
newDc.SelectObject(newBitmap)
newDc.Blit(0, 0, *self.canvasBitmap.GetSize(), oldDc, 0, 0) newDc.Blit(0, 0, *self.canvasBitmap.GetSize(), oldDc, 0, 0)
oldDc.SelectObject(wx.NullBitmap) oldDc.SelectObject(wx.NullBitmap)
self.canvasBitmap.Destroy(); self.canvasBitmap = newBitmap; self.canvasBitmap.Destroy(); self.canvasBitmap = newBitmap;
self.canvasSize = canvasSize; self.cellSize = cellSize; self.canvasSize, self.cellSize = canvasSize, cellSize
self._font = wx.Font( \ self._font = wx.Font(8, wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
8, \
wx.FONTFAMILY_TELETYPE, \
wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
# }}} # }}}
# {{{ xlateEventPoint(self, event, eventDc): XXX # {{{ xlateEventPoint(self, event, eventDc): XXX
def xlateEventPoint(self, event, eventDc): def xlateEventPoint(self, event, eventDc):
eventPoint = event.GetLogicalPosition(eventDc) eventPoint = event.GetLogicalPosition(eventDc)
rectX = eventPoint.x - (eventPoint.x % self.cellSize[0]) rectX, rectY = eventPoint.x - (eventPoint.x % self.cellSize[0]), eventPoint.y - (eventPoint.y % self.cellSize[1])
rectY = eventPoint.y - (eventPoint.y % self.cellSize[1]) mapX, mapY = int(rectX / self.cellSize[0] if rectX else 0), int(rectY / self.cellSize[1] if rectY else 0)
mapX = int(rectX / self.cellSize[0] if rectX else 0)
mapY = int(rectY / self.cellSize[1] if rectY else 0)
return (mapX, mapY) return (mapX, mapY)
# }}} # }}}
@ -149,7 +119,6 @@ class CanvasBackend():
def __init__(self, canvasSize, cellSize): def __init__(self, canvasSize, cellSize):
self._brushes, self._font, self._lastBrush, self._lastPen, self._pens = None, None, None, None, None self._brushes, self._font, self._lastBrush, self._lastPen, self._pens = None, None, None, None, None
self.canvasBitmap, self.cellSize = None, None self.canvasBitmap, self.cellSize = None, None
self._initBrushesAndPens() self._initBrushesAndPens(); self.reset(canvasSize, cellSize);
self.reset(canvasSize, cellSize)
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 # vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -31,38 +31,19 @@ class CanvasExportStore():
ImgurUploadUrl = "https://api.imgur.com/3/upload.json" ImgurUploadUrl = "https://api.imgur.com/3/upload.json"
PastebinPostUrl = "https://pastebin.com/api/api_post.php" PastebinPostUrl = "https://pastebin.com/api/api_post.php"
# {{{ _drawUnderline(self, curPos, fontSize, imgDraw, fillColour): XXX # {{{ _drawUnderline(self, curPos, fillColour, fontSize, imgDraw): XXX
def _drawUnderLine(self, curPos, fontSize, imgDraw, fillColour): def _drawUnderLine(self, curPos, fillColour, fontSize, imgDraw):
imgDraw.line( \ imgDraw.line( \
xy=(curPos[0], curPos[1] + (fontSize[1] - 2), \ xy=(curPos[0], curPos[1] + (fontSize[1] - 2), \
curPos[0] + fontSize[0], curPos[1] + (fontSize[1] - 2)), \ curPos[0] + fontSize[0], curPos[1] + (fontSize[1] - 2)), \
fill=fillColour) fill=fillColour)
# }}} # }}}
# {{{ _exportFileToImgur(self, apiKey, imgName, imgTitle, pathName): upload single PNG file to Imgur
def _exportFileToImgur(self, apiKey, imgName, imgTitle, pathName):
with open(pathName, "rb") as requestImage:
requestImageData = requestImage.read()
requestData = { \
"image": base64.b64encode(requestImageData), \
"key": apiKey, \
"name": imgName, \
"title": imgTitle, \
"type": "base64"}
requestHeaders = {"Authorization": "Client-ID " + apiKey}
responseHttp = requests.post(self.ImgurUploadUrl, data=requestData, headers=requestHeaders)
responseDict = json.loads(responseHttp.text)
if responseHttp.status_code == 200:
return [200, responseDict.get("data").get("link")]
else:
return [responseHttp.status_code, ""]
# }}}
# {{{ exportAnsiFile(self, canvasMap, canvasSize, outFile): XXX # {{{ exportAnsiFile(self, canvasMap, canvasSize, outFile): XXX
def exportAnsiFile(self, canvasMap, canvasSize, outFile): def exportAnsiFile(self, canvasMap, canvasSize, outFile):
outBuffer = "" outBuffer = ""
for inCurRow in range(len(canvasMap)): for inCurRow in range(len(canvasMap)):
lastAttribs = self._CellState.CS_NONE lastAttribs, lastColours = self._CellState.CS_NONE, None
lastColours = None
for inCurCol in range(len(canvasMap[inCurRow])): for inCurCol in range(len(canvasMap[inCurRow])):
inCurCell = canvasMap[inCurRow][inCurCol] inCurCell = canvasMap[inCurRow][inCurCol]
if lastAttribs != inCurCell[2]: if lastAttribs != inCurCell[2]:
@ -79,14 +60,32 @@ class CanvasExportStore():
else: else:
outBuffer += inCurCell[3] outBuffer += inCurCell[3]
outBuffer += "\u001b[0m\n" outBuffer += "\u001b[0m\n"
outFile.write(outBuffer) if len(outBuffer):
outFile.write(outBuffer)
return (True, None)
else:
return (False, "empty buffer generated")
# }}} # }}}
# {{{ exportBitmapToImgur(self, apiKey, canvasBitmap, imgName, imgTitle, imgType): XXX # {{{ exportBitmapToImgur(self, apiKey, canvasBitmap, imgName, imgTitle, imgType): XXX
def exportBitmapToImgur(self, apiKey, canvasBitmap, imgName, imgTitle, imgType): def exportBitmapToImgur(self, apiKey, canvasBitmap, imgName, imgTitle, imgType):
tmpPathName = tempfile.mkstemp() tmpPathName = tempfile.mkstemp()
os.close(tmpPathName[0]) os.close(tmpPathName[0])
canvasBitmap.ConvertToImage().SaveFile(tmpPathName[1], imgType) canvasBitmap.ConvertToImage().SaveFile(tmpPathName[1], imgType)
imgurResult = self._exportFileToImgur(apiKey, imgName, imgTitle, tmpPathName[1]) with open(tmpPathName[1], "rb") as requestImage:
requestImageData = requestImage.read()
requestData = { \
"image": base64.b64encode(requestImageData), \
"key": apiKey, \
"name": imgName, \
"title": imgTitle, \
"type": "base64"}
requestHeaders = {"Authorization": "Client-ID " + apiKey}
responseHttp = requests.post(self.ImgurUploadUrl, data=requestData, headers=requestHeaders)
responseDict = json.loads(responseHttp.text)
if responseHttp.status_code == 200:
imgurResult = (True, responseHttp.status_code, responseDict.get("data").get("link"))
else:
imgurResult = (False, responseHttp.status_code, responseDict.get("data"))
os.remove(tmpPathName[1]) os.remove(tmpPathName[1])
return imgurResult return imgurResult
# }}} # }}}
@ -107,39 +106,32 @@ class CanvasExportStore():
"api_paste_private": pastePrivate} "api_paste_private": pastePrivate}
responseHttp = requests.post(self.PastebinPostUrl, data=requestData) responseHttp = requests.post(self.PastebinPostUrl, data=requestData)
if responseHttp.status_code == 200: if responseHttp.status_code == 200:
if responseHttp.text.startswith("http"): return (True if responseHttp.text.startswith("http") else False, responseHttp.text)
return (True, responseHttp.text)
else:
return (False, responseHttp.text)
else: else:
return (False, str(responseHttp.status_code)) return (False, str(responseHttp.status_code))
else: else:
return (False, "missing requests and/or urllib3 module(s)") return (False, "missing requests and/or urllib3 module(s)")
# }}} # }}}
# {{{ exportPngFile(self, canvasMap, outPathName, fontFilePath, fontSize): XXX # {{{ exportPngFile(self, canvasMap, fontFilePath, fontSize, outPathName): XXX
def exportPngFile(self, canvasMap, outPathName, fontFilePath, fontSize): def exportPngFile(self, canvasMap, fontFilePath, fontSize, outPathName):
if havePIL: if havePIL:
inSize = (len(canvasMap[0]), len(canvasMap))
outCurPos = [0, 0]
outFontFilePath, outFontSize = fontFilePath, fontSize outFontFilePath, outFontSize = fontFilePath, fontSize
outImgFont = ImageFont.truetype(outFontFilePath, outFontSize) outImgFont = ImageFont.truetype(outFontFilePath, outFontSize)
outImgFontSize = [*outImgFont.getsize(" ")] outImgFontSize = [*outImgFont.getsize(" ")]; outImgFontSize[1] += 3;
outImgFontSize[1] += 3 outSize = [a * b for a, b in zip(inSize, outImgFontSize)]
inSize = (len(canvasMap[0]), len(canvasMap))
outSize = [a*b for a,b in zip(inSize, outImgFontSize)]
outCurPos = [0, 0]
outImg = Image.new("RGBA", outSize, (*ColourMapNormal[1], 255)) outImg = Image.new("RGBA", outSize, (*ColourMapNormal[1], 255))
outImgDraw = ImageDraw.Draw(outImg) outImgDraw = ImageDraw.Draw(outImg); outImgDraw.fontmode = "1";
outImgDraw.fontmode = "1"
for inCurRow in range(len(canvasMap)): for inCurRow in range(len(canvasMap)):
for inCurCol in range(len(canvasMap[inCurRow])): for inCurCol in range(len(canvasMap[inCurRow])):
inCurCell = canvasMap[inCurRow][inCurCol] inCurCell = canvasMap[inCurRow][inCurCol]; outColours = (0, 0);
outColours = [0, 0]
if inCurCell[2] & self._CellState.CS_BOLD: if inCurCell[2] & self._CellState.CS_BOLD:
if inCurCell[3] != " ": if inCurCell[3] != " ":
if inCurCell[3] == "": if inCurCell[3] == "":
outColours[1] = ColourMapNormal[inCurCell[0]] outColours[1] = ColourMapNormal[inCurCell[0]]
else: else:
outColours[0] = ColourMapBold[inCurCell[0]] outColours = (ColourMapBold[inCurCell[0]], ColourMapNormal[inCurCell[1]])
outColours[1] = ColourMapNormal[inCurCell[1]]
else: else:
outColours[1] = ColourMapNormal[inCurCell[1]] outColours[1] = ColourMapNormal[inCurCell[1]]
else: else:
@ -147,8 +139,7 @@ class CanvasExportStore():
if inCurCell[3] == "": if inCurCell[3] == "":
outColours[1] = ColourMapNormal[inCurCell[0]] outColours[1] = ColourMapNormal[inCurCell[0]]
else: else:
outColours[0] = ColourMapNormal[inCurCell[0]] outColours = (ColourMapNormal[inCurCell[0]], ColourMapNormal[inCurCell[1]])
outColours[1] = ColourMapNormal[inCurCell[1]]
else: else:
outColours[1] = ColourMapNormal[inCurCell[1]] outColours[1] = ColourMapNormal[inCurCell[1]]
outImgDraw.rectangle((*outCurPos, outCurPos[0] + outImgFontSize[0], outCurPos[1] + outImgFontSize[1]), fill=(*outColours[1], 255)) outImgDraw.rectangle((*outCurPos, outCurPos[0] + outImgFontSize[0], outCurPos[1] + outImgFontSize[1]), fill=(*outColours[1], 255))
@ -158,14 +149,13 @@ class CanvasExportStore():
outImgDraw.text(outCurPos, inCurCell[3], (*outColours[0], 255), outImgFont) outImgDraw.text(outCurPos, inCurCell[3], (*outColours[0], 255), outImgFont)
if inCurCell[2] & self._CellState.CS_UNDERLINE: if inCurCell[2] & self._CellState.CS_UNDERLINE:
outColours[0] = ColourMapNormal[inCurCell[0]] outColours[0] = ColourMapNormal[inCurCell[0]]
self._drawUnderLine(outCurPos, outImgFontSize, outImgDraw, (*outColours[0], 255)) self._drawUnderLine(outCurPos, (*outColours[0], 255), outImgFontSize, outImgDraw)
outCurPos[0] += outImgFontSize[0]; outCurPos[0] += outImgFontSize[0];
outCurPos[0] = 0 outCurPos[0] = 0; outCurPos[1] += outImgFontSize[1];
outCurPos[1] += outImgFontSize[1]
outImg.save(outPathName); outImg.save(outPathName);
return True return (True, None)
else: else:
return False return (False, "missing PIL modules")
# }}} # }}}
# {{{ exportTextBuffer(self, canvasMap, canvasSize): XXX # {{{ exportTextBuffer(self, canvasMap, canvasSize): XXX
def exportTextBuffer(self, canvasMap, canvasSize): def exportTextBuffer(self, canvasMap, canvasSize):
@ -191,12 +181,15 @@ class CanvasExportStore():
canvasLastColours[0] = canvasColColours[0] canvasLastColours[0] = canvasColColours[0]
outBuffer += canvasColText outBuffer += canvasColText
outBuffer += "\n" outBuffer += "\n"
return outBuffer if len(outBuffer):
return (True, outBuffer)
else:
return (False, "empty buffer generated")
# }}} # }}}
# {{{ exportTextFile(self, canvasMap, canvasSize, outFile): XXX # {{{ exportTextFile(self, canvasMap, canvasSize, outFile): XXX
def exportTextFile(self, canvasMap, canvasSize, outFile): def exportTextFile(self, canvasMap, canvasSize, outFile):
outBuffer = self.exportTextBuffer(canvasMap, canvasSize) rc, outBuffer = self.exportTextBuffer(canvasMap, canvasSize)
outFile.write(outBuffer) return outFile.write(outBuffer) if rc else (rc, outBuffer)
# }}} # }}}
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 # vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -17,271 +17,129 @@ class CanvasImportStore():
CS_ITALIC = 0x02 CS_ITALIC = 0x02
CS_UNDERLINE = 0x04 CS_UNDERLINE = 0x04
# }}} # }}}
# {{{ _ParseState(): Parsing loop state
class _ParseState():
PS_CHAR = 1
PS_COLOUR_DIGIT0 = 2
PS_COLOUR_DIGIT1 = 3
# }}}
# {{{ _flipCellStateBit(self, cellState, bit): XXX # {{{ _flipCellStateBit(self, bit, cellState): XXX
def _flipCellStateBit(self, cellState, bit): def _flipCellStateBit(self, bit, cellState):
return cellState & ~bit if cellState & bit else cellState | bit return cellState & ~bit if cellState & bit else cellState | bit
# }}} # }}}
# {{{ _parseCharAsColourSpec(self, colourSpec, curColours): XXX
def _parseCharAsColourSpec(self, colourSpec, curColours):
if len(colourSpec) > 0:
colourSpec = colourSpec.split(",")
if len(colourSpec) == 2 \
and len(colourSpec[1]) > 0:
return (int(colourSpec[0] or curColours[0]), int(colourSpec[1]))
elif len(colourSpec) == 1 \
or len(colourSpec[1]) == 0:
return (int(colourSpec[0]), curColours[1])
else:
return (15, 1)
# }}}
# {{{ importAnsiFile(self, inPathName, encoding="cp437"): XXX # {{{ importAnsiBuffer(self, inFile, encoding="cp437", width=None): XXX
def importAnsiFile(self, inPathName, encoding="cp437"): def importAnsiBuffer(self, inFile, encoding="cp437", width=None):
return self.importAnsiFileBuffer(open(inPathName, "rb"), encoding) curBg, curBgAnsi, curBoldAnsi, curFg, curFgAnsi = 1, 30, False, 15, 37
# }}} done, outMap, outMaxCols = False, [[]], 0
# {{{ importAnsiFileBuffer(self, inFile, encoding="cp437"): XXX inFileData = inFile.read().decode(encoding)
def importAnsiFileBuffer(self, inFile, encoding="cp437"):
self.inSize, self.outMap = None, None; inMaxCols, inSize, outMap = 0, [0, 0], [[]];
inFileData, row, rowChars = inFile.read().decode(encoding), "", 0
inFileChar, inFileCharMax = 0, len(inFileData) inFileChar, inFileCharMax = 0, len(inFileData)
curBg, curFg, done, inCurRow = 1, 15, False, 0; curBgAnsi, curBoldAnsi, curFgAnsi = 30, False, 37;
while True: while True:
if inFileChar >= inFileCharMax: if inFileChar >= inFileCharMax:
break break
else: else:
m = re.match('\x1b\[((?:\d{1,3};?)+)m', inFileData[inFileChar:]) m = re.match("\x1b\[((?:\d{1,3};?)+m|\d+C)", inFileData[inFileChar:])
if m: if m:
newBg, newFg = -1, -1 if m[1][-1] == "C":
for ansiCode in m[1].split(";"): outMap[-1] += [[curFg, curBg, self._CellState.CS_NONE, " "]] * int(m[1][:-1])
ansiCode = int(ansiCode) elif m[1][-1] == "m":
if ansiCode == 0: newBg, newFg = -1, -1
curBgAnsi, curBoldAnsi, curFgAnsi = 30, False, 37; newBg, newFg = 1, 15; for ansiCode in [int(c) for c in m[1][:-1].split(";")]:
elif ansiCode == 1: if ansiCode == 0:
curBoldAnsi, newFg = True, AnsiFgBoldToMiRCARTColours[curFgAnsi] curBgAnsi, curBoldAnsi, curFgAnsi, newBg, newFg = 30, False, 37, 1, 15
elif ansiCode == 2: elif ansiCode == 1:
curBoldAnsi, newFg = False, AnsiFgToMiRCARTColours[curFgAnsi] curBoldAnsi, newFg = True, AnsiFgBoldToMiRCARTColours[curFgAnsi]
elif ansiCode == 7: elif ansiCode == 2:
newBg, newFg = curFg, curBg; curBgAnsi, curFgAnsi = curFgAnsi, curBgAnsi; curBoldAnsi, newFg = False, AnsiFgToMiRCARTColours[curFgAnsi]
elif ansiCode in AnsiBgToMiRCARTColours: elif ansiCode == 7:
curBgAnsi, newBg = ansiCode, AnsiBgToMiRCARTColours[ansiCode] curBgAnsi, curFgAnsi, newBg, newFg = curFgAnsi, curBgAnsi, curFg, curBg
elif ansiCode in AnsiFgToMiRCARTColours: elif ansiCode in AnsiBgToMiRCARTColours:
if curBoldAnsi: curBgAnsi, newBg = ansiCode, AnsiBgToMiRCARTColours[ansiCode]
newFg = AnsiFgBoldToMiRCARTColours[ansiCode] elif ansiCode in AnsiFgBoldToMiRCARTColours:
else: curFgAnsi, newFg = ansiCode, AnsiFgBoldToMiRCARTColours[ansiCode]
newFg = AnsiFgToMiRCARTColours[ansiCode] elif ansiCode in AnsiFgToMiRCARTColours:
curFgAnsi = ansiCode newFg = AnsiFgBoldToMiRCARTColours[ansiCode] if curBoldAnsi else AnsiFgToMiRCARTColours[ansiCode]
elif ansiCode in AnsiFgBoldToMiRCARTColours: curFgAnsi = ansiCode
curFgAnsi, newFg = ansiCode, AnsiFgBoldToMiRCARTColours[ansiCode] curBg = newBg if newBg != -1 else curBg; curFg = newFg if newFg != -1 else curFg;
if ((newBg != -1) and (newFg != -1)) \
and ((newBg == curFg) and (newFg == curBg)):
curBg, curFg = newBg, newFg
elif ((newBg != -1) and (newFg != -1)) \
and ((newBg != curBg) and (newFg != curFg)):
curBg, curFg = newBg, newFg
elif (newBg != -1) and (newBg != curBg):
curBg = newBg
elif (newFg != -1) and (newFg != curFg):
curFg = newFg
inFileChar += len(m[0]) inFileChar += len(m[0])
elif inFileData[inFileChar:inFileChar + 2] == "\r\n":
done = True; inFileChar += 2;
elif inFileData[inFileChar] in set("\r\n"):
done = True; inFileChar += 1;
else: else:
m = re.match('\x1b\[(\d+)C', inFileData[inFileChar:]) outMap[-1].append([curFg, curBg, self._CellState.CS_NONE, inFileData[inFileChar]])
if m: inFileChar += 1
for numRepeat in range(int(m[1])): if done or (width == len(outMap[-1])):
outMap[inCurRow].append([curFg, curBg, self._CellState.CS_NONE, " "]) done, outMaxCols, = False, max(outMaxCols, len(outMap[-1])); outMap.append([]);
inFileChar += len(m[0]) if len(outMap[0]):
elif inFileData[inFileChar:inFileChar+2] == "\r\n": for numRow in range(len(outMap)):
inFileChar += 2; done = True; for numCol in range(len(outMap[numRow]), outMaxCols):
elif inFileData[inFileChar] == "\r" \ outMap[numRow].append([curFg, curBg, self._CellState.CS_NONE, " "])
or inFileData[inFileChar] == "\n": self.inSize, self.outMap = [outMaxCols, len(outMap)], outMap
inFileChar += 1; done = True; return (True, None)
else: else:
outMap[inCurRow].append([curFg, curBg, self._CellState.CS_NONE, inFileData[inFileChar]]) return (False, "empty output map")
inFileChar += 1; rowChars += 1;
if done:
inMaxCols = max(inMaxCols, len(outMap[inCurRow])); inSize[1] += 1;
done = False; rowChars = 0; inCurRow += 1; outMap.append([]);
inSize[0] = inMaxCols
for numRow in range(inSize[1]):
for numCol in range(len(outMap[numRow]), inSize[0]):
outMap[numRow].append([curFg, curBg, self._CellState.CS_NONE, " "])
self.inSize, self.outMap = inSize, outMap
# }}} # }}}
# {{{ importIntoPanel(self): XXX # {{{ importAnsiFile(self, inPathName, encoding="cp437"): XXX
def importIntoPanel(self): def importAnsiFile(self, inPathName, encoding="cp437"):
self.parentCanvas.onStoreUpdate(self.inSize, self.outMap) return self.importAnsiBuffer(open(inPathName, "rb"), encoding)
# }}}
# {{{ importNew(self, newCanvasSize=None): XXX
def importNew(self, newCanvasSize=None):
newMap = [[[1, 1, 0, " "] \
for x in range(newCanvasSize[0])] \
for y in range(newCanvasSize[1])]
self.parentCanvas.onStoreUpdate(newCanvasSize, newMap)
# }}} # }}}
# {{{ importSauceFile(self, inPathName): XXX # {{{ importSauceFile(self, inPathName): XXX
def importSauceFile(self, inPathName): def importSauceFile(self, inPathName):
with open(inPathName, "rb") as inFile: with open(inPathName, "rb") as inFile:
self.inSize, self.outMap = None, None; inMaxCols, inSize, outMap = 0, [0, 0], [[]]; inFileStat = os.stat(inPathName); inFile.seek(inFileStat.st_size - 128, 0); inFile.seek(94);
inFileStat = os.stat(inPathName) if inFile.read(2) == b'\x01\x01':
inFile.seek(inFileStat.st_size - 128, 0) width = struct.unpack("H", inFile.read(2))[0]
inFile.seek(5 + 2 + 35 + 20 + 20 + 8 + 4, 1) inFile.seek(0, 0); inFileData = inFile.read(inFileStat.st_size - 128);
if (inFile.read(1) == b'\x01') \ return self.importAnsiFileBuffer(io.StringIO(inFileData), width)
and (inFile.read(1) == b'\x01'): else:
width, height = struct.unpack("H", inFile.read(2))[0], struct.unpack("H", inFile.read(2))[0] return (False, "only character based ANSi SAUCE files are supported")
inFile.seek(0, 0) # }}}
inFileData, row, rowChars = inFile.read(inFileStat.st_size - 128).decode("cp437"), "", 0 # {{{ importTextBuffer(self, inFile): XXX
inFileChar, inFileCharMax = 0, len(inFileData) def importTextBuffer(self, inFile):
curBg, curFg, inCurRow = 1, 15, 0; curBgAnsi, curBoldAnsi, curFgAnsi = 30, False, 37; inLine, outMap, outMaxCols = inFile.readline(), [], 0
while True: while inLine:
if inFileChar >= inFileCharMax: inCellState, inCurCol, inCurColours, inMaxCol = self._CellState.CS_NONE, 0, (15, 1), len(inLine); outMap.append([]);
break while inCurCol < inMaxCol:
else: inChar = inLine[inCurCol]
m = re.match('\x1b\[((?:\d{1,3};?)+)m', inFileData[inFileChar:]) if inChar in set("\r\n"):
if m: inCurCol += 1
newBg, newFg = -1, -1 elif inChar == "\u0002":
for ansiCode in m[1].split(";"): inCellState = self._flipCellStateBit(self._CellState.CS_BOLD, inCellState); inCurCol += 1;
ansiCode = int(ansiCode) elif inChar == "\u0003":
if ansiCode == 0: m = re.match("\u0003((1[0-5]|0?[0-9])?(?:,(1[0-5]|0?[0-9]))?)", inLine[inCurCol:])
curBgAnsi, curBoldAnsi, curFgAnsi = 30, False, 37; newBg, newFg = 1, 15; if m:
elif ansiCode == 1: if (m[2] != None) and (m[3] != None):
curBoldAnsi, newFg = True, AnsiFgBoldToMiRCARTColours[curFgAnsi] inCurColours = (int(m[2]), int(m[3]))
elif ansiCode == 2: elif (m[2] == None) and (m[3] != None):
curBoldAnsi, newFg = False, AnsiFgToMiRCARTColours[curFgAnsi] inCurColours = (int(m[2]), int(curColours[1]))
elif ansiCode == 7:
newBg, newFg = curFg, curBg; curBgAnsi, curFgAnsi = curFgAnsi, curBgAnsi;
elif ansiCode in AnsiBgToMiRCARTColours:
curBgAnsi, newBg = ansiCode, AnsiBgToMiRCARTColours[ansiCode]
elif ansiCode in AnsiFgToMiRCARTColours:
if curBoldAnsi:
newFg = AnsiFgBoldToMiRCARTColours[ansiCode]
else:
newFg = AnsiFgToMiRCARTColours[ansiCode]
curFgAnsi = ansiCode
elif ansiCode in AnsiFgBoldToMiRCARTColours:
curFgAnsi, newFg = ansiCode, AnsiFgBoldToMiRCARTColours[ansiCode]
if ((newBg != -1) and (newFg != -1)) \
and ((newBg == curFg) and (newFg == curBg)):
curBg, curFg = newBg, newFg
elif ((newBg != -1) and (newFg != -1)) \
and ((newBg != curBg) and (newFg != curFg)):
curBg, curFg = newBg, newFg
elif (newBg != -1) and (newBg != curBg):
curBg = newBg
elif (newFg != -1) and (newFg != curFg):
curFg = newFg
inFileChar += len(m[0])
else: else:
m = re.match('\x1b\[(\d+)C', inFileData[inFileChar:]) inCurColours = (15, 1)
if m: inCurCol += len(m[0])
for numRepeat in range(int(m[1])): else:
outMap[inCurRow].append([curFg, curBg, self._CellState.CS_NONE, " "]) inCurColours = (15, 1); inCurCol += 1;
inFileChar += len(m[0]) elif inChar == "\u0006":
elif inFileData[inFileChar:inFileChar+2] == "\r\n": inCellState = self._flipCellStateBit(self._CellState.CS_ITALIC, inCellState); inCurCol += 1;
inFileChar += 2; rowChars = width; elif inChar == "\u000f":
elif inFileData[inFileChar] == "\r" \ inCellState |= self._CellState.CS_NONE; inCurColours = (15, 1); inCurCol += 1;
or inFileData[inFileChar] == "\n": elif inChar == "\u0016":
inFileChar += 1; rowChars = width; inCurColours = (inCurColours[1], inCurColours[0]); inCurCol += 1;
else: elif inChar == "\u001f":
outMap[inCurRow].append([curFg, curBg, self._CellState.CS_NONE, inFileData[inFileChar]]) inCellState = self._flipCellStateBit(self._CellState.CS_UNDERLINE, inCellState); inCurCol += 1;
inFileChar += 1; rowChars += 1; else:
if rowChars >= width: outMap[-1].append([*inCurColours, inCellState, inChar]); inCurCol += 1;
inMaxCols = max(inMaxCols, len(outMap[inCurRow])); inSize[1] += 1; inLine, outMaxCols = inFile.readline(), max(outMaxCols, len(outMap[-1]))
rowChars = 0; inCurRow += 1; outMap.append([]); if len(outMap[0]):
inSize[0] = inMaxCols self.inSize, self.outMap = [outMaxCols, len(outMap)], outMap
for numRow in range(inSize[1]): return (True, None)
for numCol in range(len(outMap[numRow]), inSize[0]): else:
outMap[numRow].append([curFg, curBg, self._CellState.CS_NONE, " "]) return (False, "empty output map")
self.inSize, self.outMap = inSize, outMap
# }}} # }}}
# {{{ importTextFile(self, pathName): XXX # {{{ importTextFile(self, pathName): XXX
def importTextFile(self, pathName): def importTextFile(self, pathName):
return self.importTextFileBuffer(open(pathName, "r", encoding="utf-8-sig")) with open(pathName, "r", encoding="utf-8-sig") as inFile:
# }}} return self.importTextBuffer(inFile)
# {{{ importTextFileBuffer(self, inFile): XXX
def importTextFileBuffer(self, inFile):
self.inSize, self.outMap = None, None
inCurColourSpec, inCurRow, inMaxCols, inSize, outMap = "", -1, 0, [0, 0], []
inLine = inFile.readline()
while inLine:
inCellState = self._CellState.CS_NONE
inParseState = self._ParseState.PS_CHAR
inCurCol = 0; inMaxCol = len(inLine);
inCurColourDigits = 0; inCurColours = (15, 1); inCurColourSpec = "";
inCurRow += 1; outMap.append([]); inRowCols = 0; inSize[1] += 1;
while inCurCol < inMaxCol:
inChar = inLine[inCurCol]
if inChar in set("\r\n"): \
inCurCol += 1
elif inParseState == self._ParseState.PS_CHAR:
inCurCol += 1
if inChar == "":
inCellState = self._flipCellStateBit( \
inCellState, self._CellState.CS_BOLD)
elif inChar == "":
inParseState = self._ParseState.PS_COLOUR_DIGIT0
elif inChar == "":
inCellState = self._flipCellStateBit( \
inCellState, self._CellState.CS_ITALIC)
elif inChar == "":
inCellState |= self._CellState.CS_NONE
inCurColours = (15, 1)
elif inChar == "":
inCurColours = (inCurColours[1], inCurColours[0])
elif inChar == "":
inCellState = self._flipCellStateBit( \
inCellState, self._CellState.CS_UNDERLINE)
else:
inRowCols += 1
outMap[inCurRow].append([*inCurColours, inCellState, inChar])
elif inParseState == self._ParseState.PS_COLOUR_DIGIT0 \
or inParseState == self._ParseState.PS_COLOUR_DIGIT1:
if inChar == "," \
and inParseState == self._ParseState.PS_COLOUR_DIGIT0:
if (inCurCol + 1) < inMaxCol \
and not inLine[inCurCol + 1] in set("0123456789"):
inCurColours = self._parseCharAsColourSpec( \
inCurColourSpec, inCurColours)
inCurColourDigits = 0; inCurColourSpec = "";
inParseState = self._ParseState.PS_CHAR
else:
inCurCol += 1
inCurColourDigits = 0; inCurColourSpec += inChar;
inParseState = self._ParseState.PS_COLOUR_DIGIT1
elif inChar in set("0123456789") \
and inCurColourDigits == 0:
inCurCol += 1
inCurColourDigits += 1; inCurColourSpec += inChar;
elif inChar in set("0123456789") \
and inCurColourDigits == 1 \
and inCurColourSpec[-1] == "0":
inCurCol += 1
inCurColourDigits += 1; inCurColourSpec += inChar;
elif inChar in set("012345") \
and inCurColourDigits == 1 \
and inCurColourSpec[-1] == "1":
inCurCol += 1
inCurColourDigits += 1; inCurColourSpec += inChar;
else:
inCurColours = self._parseCharAsColourSpec( \
inCurColourSpec, inCurColours)
inCurColourDigits = 0; inCurColourSpec = "";
inParseState = self._ParseState.PS_CHAR
inMaxCols = max(inMaxCols, inRowCols)
inLine = inFile.readline()
inSize[0] = inMaxCols; self.inSize, self.outMap = inSize, outMap;
inFile.close()
# }}} # }}}
# #
# __init__(self, inFile=None, parentCanvas=None): initialisation method # __init__(self, inFile=None): initialisation method
def __init__(self, inFile=None, parentCanvas=None): def __init__(self, inFile=None):
self.inSize, self.outMap, self.parentCanvas = None, None, parentCanvas self.inSize, self.outMap = None, None
if inFile != None: if inFile != None:
self.importTextFile(inFile) self.importTextFile(inFile)

View File

@ -10,8 +10,7 @@ class CanvasJournal():
# {{{ popCursor(self): XXX # {{{ popCursor(self): XXX
def popCursor(self): def popCursor(self):
if len(self.patchesCursor): if len(self.patchesCursor):
patchesCursor = self.patchesCursor patchesCursor = self.patchesCursor; self.patchesCursor = [];
self.patchesCursor = []
return patchesCursor return patchesCursor
else: else:
return [] return []
@ -19,8 +18,7 @@ class CanvasJournal():
# {{{ popRedo(self): XXX # {{{ popRedo(self): XXX
def popRedo(self): def popRedo(self):
if self.patchesUndoLevel > 0: if self.patchesUndoLevel > 0:
self.patchesUndoLevel -= 1 self.patchesUndoLevel -= 1; patches = self.patchesUndo[self.patchesUndoLevel];
patches = self.patchesUndo[self.patchesUndoLevel]
return patches[1] return patches[1]
else: else:
return [] return []
@ -28,8 +26,7 @@ class CanvasJournal():
# {{{ popUndo(self): XXX # {{{ popUndo(self): XXX
def popUndo(self): def popUndo(self):
if self.patchesUndo[self.patchesUndoLevel] != None: if self.patchesUndo[self.patchesUndoLevel] != None:
patches = self.patchesUndo[self.patchesUndoLevel] patches = self.patchesUndo[self.patchesUndoLevel]; self.patchesUndoLevel += 1;
self.patchesUndoLevel += 1
return patches[0] return patches[0]
else: else:
return [] return []
@ -38,13 +35,11 @@ class CanvasJournal():
def pushCursor(self, patches): def pushCursor(self, patches):
self.patchesCursor.append(patches) self.patchesCursor.append(patches)
# }}} # }}}
# {{{ pushDeltas(self, undoPatches, redoPatches): XXX # {{{ pushDeltas(self, redoPatches, undoPatches): XXX
def pushDeltas(self, undoPatches, redoPatches): def pushDeltas(self, redoPatches, undoPatches):
if self.patchesUndoLevel > 0: if self.patchesUndoLevel > 0:
del self.patchesUndo[0:self.patchesUndoLevel] del self.patchesUndo[0:self.patchesUndoLevel]; self.patchesUndoLevel = 0;
self.patchesUndoLevel = 0 deltaItem = [undoPatches, redoPatches]; self.patchesUndo.insert(0, deltaItem);
deltaItem = [undoPatches, redoPatches]
self.patchesUndo.insert(0, deltaItem)
return deltaItem return deltaItem
# }}} # }}}
# {{{ resetCursor(self): XXX # {{{ resetCursor(self): XXX
@ -59,10 +54,9 @@ class CanvasJournal():
self.patchesUndo.clear() self.patchesUndo.clear()
self.patchesUndo = [None]; self.patchesUndoLevel = 0; self.patchesUndo = [None]; self.patchesUndoLevel = 0;
# }}} # }}}
# {{{ updateCurrentDeltas(self, undoPatches, redoPatches): XXX # {{{ updateCurrentDeltas(self, redoPatches, undoPatches): XXX
def updateCurrentDeltas(self, undoPatches, redoPatches): def updateCurrentDeltas(self, redoPatches, undoPatches):
self.patchesUndo[0][0].append(undoPatches) self.patchesUndo[0][0].append(undoPatches); self.patchesUndo[0][1].append(redoPatches);
self.patchesUndo[0][1].append(redoPatches)
# }}} # }}}
# {{{ __del__(self): destructor method # {{{ __del__(self): destructor method

View File

@ -126,22 +126,22 @@ Colours = [
# }}} # }}}
# {{{ MiRCARTToAnsiColours: XXX # {{{ MiRCARTToAnsiColours: XXX
MiRCARTToAnsiColours = [ MiRCARTToAnsiColours = [
97, # Bright White 97, # Bright White
30, # Black 30, # Black
94, # Light Blue 94, # Light Blue
32, # Green 32, # Green
91, # Red 91, # Red
31, # Light Red 31, # Light Red
35, # Pink 35, # Pink
33, # Yellow 33, # Yellow
93, # Light Yellow 93, # Light Yellow
92, # Light Green 92, # Light Green
36, # Cyan 36, # Cyan
96, # Light Cyan 96, # Light Cyan
34, # Blue 34, # Blue
95, # Light Pink 95, # Light Pink
90, # Grey 90, # Grey
37, # Light Grey 37, # Light Grey
]; ];
# }}} # }}}

View File

@ -5,7 +5,7 @@
# #
from ToolCircle import ToolCircle from ToolCircle import ToolCircle
from ToolFill import ToolFill from ToolFill import ToolFill
from ToolLine import ToolLine from ToolLine import ToolLine
from ToolSelectClone import ToolSelectClone from ToolSelectClone import ToolSelectClone
from ToolSelectMove import ToolSelectMove from ToolSelectMove import ToolSelectMove
@ -19,13 +19,11 @@ import io, os, random, wx, wx.adv
class GuiCanvasInterface(): class GuiCanvasInterface():
"""XXX""" """XXX"""
# {{{ _dialogSaveChanges(self): XXX
# {{{ _dialogSaveChanges(self)
def _dialogSaveChanges(self): def _dialogSaveChanges(self):
with wx.MessageDialog(self.parentCanvas, \ with wx.MessageDialog(self.parentCanvas, \
"Do you want to save changes to {}?".format( \ "Do you want to save changes to {}?".format(self.canvasPathName), \
self.canvasPathName), "", \ "", wx.CANCEL|wx.CANCEL_DEFAULT|wx.ICON_QUESTION|wx.YES_NO) as dialog:
wx.CANCEL|wx.CANCEL_DEFAULT|wx.ICON_QUESTION|wx.YES_NO) as dialog:
dialogChoice = dialog.ShowModal() dialogChoice = dialog.ShowModal()
return dialogChoice return dialogChoice
# }}} # }}}
@ -54,6 +52,105 @@ class GuiCanvasInterface():
def canvasCut(self, event): def canvasCut(self, event):
pass pass
# }}} # }}}
# {{{ canvasDelete(self, event): XXX
def canvasDelete(self, event):
pass
# }}}
# {{{ canvasExit(self, event): XXX
def canvasExit(self, event):
if self.canvasPathName != None:
saveChanges = self._dialogSaveChanges()
if saveChanges == wx.ID_CANCEL:
return
elif saveChanges == wx.ID_NO:
pass
elif saveChanges == wx.ID_YES:
self.canvasSave(event)
self.parentFrame.Close(True)
# }}}
# {{{ canvasNew(self, event, newCanvasSize=None): XXX
def canvasNew(self, event, newCanvasSize=None):
if self.canvasPathName != None:
saveChanges = self._dialogSaveChanges()
if saveChanges == wx.ID_CANCEL:
return
elif saveChanges == wx.ID_NO:
pass
elif saveChanges == wx.ID_YES:
self.canvasSave(event)
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
if newCanvasSize == None:
newCanvasSize = list(self.parentCanvas.defaultCanvasSize)
newMap = [[[1, 1, 0, " "] for x in range(newCanvasSize[0])] for y in range(newCanvasSize[1])]
self.parentCanvas.onStoreUpdate(newCanvasSize, newMap)
self.canvasPathName = None
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
self.parentFrame.onCanvasUpdate(pathName="", undoLevel=-1)
# }}}
# {{{ canvasOpen(self, event): XXX
def canvasOpen(self, event):
if self.canvasPathName != None:
saveChanges = self._dialogSaveChanges()
if saveChanges == wx.ID_CANCEL:
return
elif saveChanges == wx.ID_NO:
pass
elif saveChanges == wx.ID_YES:
self.canvasSave(event)
with wx.FileDialog(self.parentCanvas, "Open", os.getcwd(), "", "mIRC art files (*.txt)|*.txt|All Files (*.*)|*.*", wx.FD_OPEN) as dialog:
if dialog.ShowModal() == wx.ID_CANCEL:
return False
else:
self.canvasPathName = dialog.GetPath()
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
import pdb; pdb.set_trace()
rc, error = self.parentCanvas.canvasImportStore.importTextFile(self.canvasPathName)
if rc:
self.parentCanvas.onStoreUpdate(self.parentCanvas.canvasImportStore.inSize, self.parentCanvas.canvasImportStore.outMap)
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
self.parentFrame.onCanvasUpdate(pathName=self.canvasPathName, undoLevel=-1)
return True
else:
print("error: {}".format(error), file=sys.stderr)
return False
# }}}
# {{{ canvasPaste(self, event): XXX
def canvasPaste(self, event):
pass
# }}}
# {{{ canvasRedo(self, event): XXX
def canvasRedo(self, event):
self.parentCanvas._dispatchDeltaPatches(self.parentCanvas.canvasJournal.popRedo())
# }}}
# {{{ canvasSave(self, event): XXX
def canvasSave(self, event):
if self.canvasPathName == None:
if self.canvasSaveAs(event) == False:
return
try:
with open(self.canvasPathName, "w", encoding="utf-8") as outFile:
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
self.parentCanvas.canvasExportStore.exportTextFile( \
self.parentCanvas.canvasMap, self.parentCanvas.canvasSize, outFile)
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
return True
except IOError as error:
return False
# }}}
# {{{ canvasSaveAs(self, event): XXX
def canvasSaveAs(self, event):
with wx.FileDialog(self.parentCanvas, "Save As", os.getcwd(), "", "mIRC art files (*.txt)|*.txt|All Files (*.*)|*.*", wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) as dialog:
if dialog.ShowModal() == wx.ID_CANCEL:
return False
else:
self.canvasPathName = dialog.GetPath()
return self.canvasSave(event)
# }}}
# {{{ canvasUndo(self, event): XXX
def canvasUndo(self, event):
self.parentCanvas._dispatchDeltaPatches(self.parentCanvas.canvasJournal.popUndo())
# }}}
# {{{ canvasDecrBrushHeight(self, event): XXX # {{{ canvasDecrBrushHeight(self, event): XXX
def canvasDecrBrushHeight(self, event): def canvasDecrBrushHeight(self, event):
if self.parentCanvas.brushSize[1] > 1: if self.parentCanvas.brushSize[1] > 1:
@ -74,9 +171,7 @@ class GuiCanvasInterface():
# {{{ canvasDecrCanvasHeight(self, event): XXX # {{{ canvasDecrCanvasHeight(self, event): XXX
def canvasDecrCanvasHeight(self, event): def canvasDecrCanvasHeight(self, event):
if self.parentCanvas.canvasSize[1] > 1: if self.parentCanvas.canvasSize[1] > 1:
self.parentCanvas.resize([ \ self.parentCanvas.resize([self.parentCanvas.canvasSize[0], self.parentCanvas.canvasSize[1] - 1])
self.parentCanvas.canvasSize[0], \
self.parentCanvas.canvasSize[1]-1])
# }}} # }}}
# {{{ canvasDecrCanvasHeightWidth(self, event): XXX # {{{ canvasDecrCanvasHeightWidth(self, event): XXX
def canvasDecrCanvasHeightWidth(self, event): def canvasDecrCanvasHeightWidth(self, event):
@ -86,36 +181,37 @@ class GuiCanvasInterface():
# {{{ canvasDecrCanvasWidth(self, event): XXX # {{{ canvasDecrCanvasWidth(self, event): XXX
def canvasDecrCanvasWidth(self, event): def canvasDecrCanvasWidth(self, event):
if self.parentCanvas.canvasSize[0] > 1: if self.parentCanvas.canvasSize[0] > 1:
self.parentCanvas.resize([ \ self.parentCanvas.resize([self.parentCanvas.canvasSize[0] - 1, self.parentCanvas.canvasSize[1]])
self.parentCanvas.canvasSize[0]-1, \
self.parentCanvas.canvasSize[1]])
# }}} # }}}
# {{{ canvasDelete(self, event): XXX # {{{ canvasIncrBrushHeight(self, event): XXX
def canvasDelete(self, event): def canvasIncrBrushHeight(self, event):
pass self.parentCanvas.brushSize[1] += 1
self.parentFrame.onCanvasUpdate(brushSize=self.parentCanvas.brushSize)
# }}} # }}}
# {{{ canvasExit(self, event): XXX # {{{ canvasIncrBrushHeightWidth(self, event): XXX
def canvasExit(self, event): def canvasIncrBrushHeightWidth(self, event):
if self.canvasPathName != None: self.canvasIncrBrushHeight(event)
saveChanges = self._dialogSaveChanges() self.canvasIncrBrushWidth(event)
if saveChanges == wx.ID_CANCEL:
return
elif saveChanges == wx.ID_NO:
pass
elif saveChanges == wx.ID_YES:
self.canvasSave(event)
self.parentFrame.Close(True)
# }}} # }}}
# {{{ canvasExportToClipboard(self, event): XXX # {{{ canvasIncrBrushWidth(self, event): XXX
def canvasExportToClipboard(self, event): def canvasIncrBrushWidth(self, event):
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) self.parentCanvas.brushSize[0] += 1
outBuffer = self.parentCanvas.canvasExportStore.exportTextBuffer(self.parentCanvas.canvasMap, self.parentCanvas.canvasSize) self.parentFrame.onCanvasUpdate(brushSize=self.parentCanvas.brushSize)
if wx.TheClipboard.Open():
wx.TheClipboard.SetData(wx.TextDataObject(outBuffer))
wx.TheClipboard.Close()
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
return True
# }}} # }}}
# {{{ canvasIncrCanvasHeight(self, event): XXX
def canvasIncrCanvasHeight(self, event):
self.parentCanvas.resize([self.parentCanvas.canvasSize[0], self.parentCanvas.canvasSize[1] + 1])
# }}}
# {{{ canvasIncrCanvasHeightWidth(self, event): XXX
def canvasIncrCanvasHeightWidth(self, event):
self.canvasIncrCanvasHeight(event)
self.canvasIncrCanvasWidth(event)
# }}}
# {{{ canvasIncrCanvasWidth(self, event): XXX
def canvasIncrCanvasWidth(self, event):
self.parentCanvas.resize([self.parentCanvas.canvasSize[0] + 1, self.parentCanvas.canvasSize[1]])
# }}}
# {{{ canvasExportAsAnsi(self, event): XXX # {{{ canvasExportAsAnsi(self, event): XXX
def canvasExportAsAnsi(self, event): def canvasExportAsAnsi(self, event):
with wx.FileDialog(self.parentFrame, "Save As...", os.getcwd(), "", "ANSI files (*.ans;*.txt)|*.ans;*.txt|All Files (*.*)|*.*", wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) as dialog: with wx.FileDialog(self.parentFrame, "Save As...", os.getcwd(), "", "ANSI files (*.ans;*.txt)|*.ans;*.txt|All Files (*.*)|*.*", wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) as dialog:
@ -137,7 +233,7 @@ class GuiCanvasInterface():
else: else:
outPathName = dialog.GetPath() outPathName = dialog.GetPath()
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
self.parentCanvas.canvasExportStore.exportBitmapToPngFile( \ self.parentCanvas.canvasExportStore.exportBitmapToPngFile( \
self.parentCanvas.canvasBackend.canvasBitmap, outPathName, wx.BITMAP_TYPE_PNG) self.parentCanvas.canvasBackend.canvasBitmap, outPathName, wx.BITMAP_TYPE_PNG)
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
return True return True
@ -145,28 +241,23 @@ class GuiCanvasInterface():
# {{{ canvasExportImgur(self, event): XXX # {{{ canvasExportImgur(self, event): XXX
def canvasExportImgur(self, event): def canvasExportImgur(self, event):
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
imgurResult = self.parentCanvas.canvasExportStore.exportBitmapToImgur( \ rc, status, result = self.parentCanvas.canvasExportStore.exportBitmapToImgur( \
self.imgurApiKey, self.parentCanvas.canvasBackend.canvasBitmap, \ self.imgurApiKey, self.parentCanvas.canvasBackend.canvasBitmap, "", "", wx.BITMAP_TYPE_PNG)
"", "", wx.BITMAP_TYPE_PNG)
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
if imgurResult[0] == 200: if rc:
if not wx.TheClipboard.IsOpened(): if not wx.TheClipboard.IsOpened():
wx.TheClipboard.Open() wx.TheClipboard.Open(); wx.TheClipboard.SetData(wx.TextDataObject(result)); wx.TheClipboard.Close();
wx.TheClipboard.SetData(wx.TextDataObject(imgurResult[1])) wx.MessageBox("Exported to Imgur: {}".format(result), "Export to Imgur", wx.ICON_INFORMATION | wx.OK)
wx.TheClipboard.Close()
wx.MessageBox("Exported to Imgur: " + imgurResult[1], \
"Export to Imgur", wx.OK|wx.ICON_INFORMATION)
else: else:
wx.MessageBox("Failed to export to Imgur: " + imgurResult[1], \ wx.MessageBox("Failed to export to Imgur: {}".format(result), "Export to Imgur", wx.ICON_EXCLAMATION | wx.OK)
"Export to Imgur", wx.OK|wx.ICON_EXCLAMATION)
# }}} # }}}
# {{{ canvasExportPastebin(self, event): XXX # {{{ canvasExportPastebin(self, event): XXX
def canvasExportPastebin(self, event): def canvasExportPastebin(self, event):
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
pasteStatus, pasteResult = \ pasteStatus, pasteResult = \
self.parentCanvas.canvasExportStore.exportPastebin( \ self.parentCanvas.canvasExportStore.exportPastebin( \
"", \ "", \
self.parentCanvas.canvasMap, \ self.parentCanvas.canvasMap, \
self.parentCanvas.canvasSize) self.parentCanvas.canvasSize)
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
if pasteStatus: if pasteStatus:
@ -174,11 +265,19 @@ class GuiCanvasInterface():
wx.TheClipboard.Open() wx.TheClipboard.Open()
wx.TheClipboard.SetData(wx.TextDataObject(pasteResult)) wx.TheClipboard.SetData(wx.TextDataObject(pasteResult))
wx.TheClipboard.Close() wx.TheClipboard.Close()
wx.MessageBox("Exported to Pastebin: " + pasteResult, \ wx.MessageBox("Exported to Pastebin: " + pasteResult, "Export to Pastebin", wx.OK|wx.ICON_INFORMATION)
"Export to Pastebin", wx.OK|wx.ICON_INFORMATION)
else: else:
wx.MessageBox("Failed to export to Pastebin: " + pasteResult, \ wx.MessageBox("Failed to export to Pastebin: " + pasteResult, "Export to Pastebin", wx.OK|wx.ICON_EXCLAMATION)
"Export to Pastebin", wx.OK|wx.ICON_EXCLAMATION) # }}}
# {{{ canvasExportToClipboard(self, event): XXX
def canvasExportToClipboard(self, event):
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
rc, outBuffer = self.parentCanvas.canvasExportStore.exportTextBuffer(self.parentCanvas.canvasMap, self.parentCanvas.canvasSize)
if rc and wx.TheClipboard.Open():
wx.TheClipboard.SetData(wx.TextDataObject(outBuffer))
wx.TheClipboard.Close()
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
return True
# }}} # }}}
# {{{ canvasImportAnsi(self, event): XXX # {{{ canvasImportAnsi(self, event): XXX
def canvasImportAnsi(self, event): def canvasImportAnsi(self, event):
@ -196,17 +295,21 @@ class GuiCanvasInterface():
else: else:
self.canvasPathName = dialog.GetPath() self.canvasPathName = dialog.GetPath()
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
self.parentCanvas.canvasImportStore.importAnsiFile(self.canvasPathName) rc, error = self.parentCanvas.canvasImportStore.importAnsiFile(self.canvasPathName)
self.parentCanvas.canvasImportStore.importIntoPanel() if rc:
self.canvasPathName = "(Imported)" self.parentCanvas.onStoreUpdate(self.parentCanvas.canvasImportStore.inSize, self.parentCanvas.canvasImportStore.outMap)
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) self.canvasPathName = "(Imported)"
self.parentFrame.onCanvasUpdate(pathName="(Imported)", undoLevel=-1) self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
return True self.parentFrame.onCanvasUpdate(pathName="(Imported)", undoLevel=-1)
return True
else:
print("error: {}".format(error), file=sys.stderr)
return False
# }}} # }}}
# {{{ canvasImportFromClipboard(self, event): XXX # {{{ canvasImportFromClipboard(self, event): XXX
def canvasImportFromClipboard(self, event): def canvasImportFromClipboard(self, event):
rc = False rc = False
if wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_TEXT)) \ if wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_TEXT)) \
and wx.TheClipboard.Open(): and wx.TheClipboard.Open():
inBuffer = wx.TextDataObject() inBuffer = wx.TextDataObject()
if wx.TheClipboard.GetData(inBuffer): if wx.TheClipboard.GetData(inBuffer):
@ -219,12 +322,14 @@ class GuiCanvasInterface():
elif saveChanges == wx.ID_YES: elif saveChanges == wx.ID_YES:
self.canvasSave(event) self.canvasSave(event)
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
self.parentCanvas.canvasImportStore.importTextFileBuffer(io.StringIO(inBuffer.GetText())) rc, error = self.parentCanvas.canvasImportStore.importTextBuffer(io.StringIO(inBuffer.GetText()))
self.parentCanvas.canvasImportStore.importIntoPanel() if rc:
self.canvasPathName = "(Clipboard)" self.parentCanvas.onStoreUpdate(self.parentCanvas.canvasImportStore.inSize, self.parentCanvas.canvasImportStore.outMap)
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) self.canvasPathName = "(Clipboard)"
self.parentFrame.onCanvasUpdate(pathName="(Clipboard)", undoLevel=-1) self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
rc = True self.parentFrame.onCanvasUpdate(pathName="(Clipboard)", undoLevel=-1)
else:
print("error: {}".format(error), file=sys.stderr)
wx.TheClipboard.Close() wx.TheClipboard.Close()
if not rc: if not rc:
with wx.MessageDialog(self.parentCanvas, "Clipboard does not contain text data and/or cannot be opened", "", wx.ICON_QUESTION | wx.OK | wx.OK_DEFAULT) as dialog: with wx.MessageDialog(self.parentCanvas, "Clipboard does not contain text data and/or cannot be opened", "", wx.ICON_QUESTION | wx.OK | wx.OK_DEFAULT) as dialog:
@ -246,121 +351,18 @@ class GuiCanvasInterface():
else: else:
self.canvasPathName = dialog.GetPath() self.canvasPathName = dialog.GetPath()
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
self.parentCanvas.canvasImportStore.importSauceFile(self.canvasPathName) rc, error = self.parentCanvas.canvasImportStore.importSauceFile(self.canvasPathName)
self.parentCanvas.canvasImportStore.importIntoPanel() if rc:
self.canvasPathName = "(Imported)" self.parentCanvas.onStoreUpdate(self.parentCanvas.canvasImportStore.inSize, self.parentCanvas.canvasImportStore.outMap)
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) self.canvasPathName = "(Imported)"
self.parentFrame.onCanvasUpdate(pathName="(Imported)", undoLevel=-1) self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
return True self.parentFrame.onCanvasUpdate(pathName="(Imported)", undoLevel=-1)
# }}} return True
# {{{ canvasIncrBrushHeight(self, event): XXX else:
def canvasIncrBrushHeight(self, event): print("error: {}".format(error), file=sys.stderr)
self.parentCanvas.brushSize[1] += 1 return False
self.parentFrame.onCanvasUpdate(brushSize=self.parentCanvas.brushSize)
# }}}
# {{{ canvasIncrBrushHeightWidth(self, event): XXX
def canvasIncrBrushHeightWidth(self, event):
self.canvasIncrBrushHeight(event)
self.canvasIncrBrushWidth(event)
# }}}
# {{{ canvasIncrBrushWidth(self, event): XXX
def canvasIncrBrushWidth(self, event):
self.parentCanvas.brushSize[0] += 1
self.parentFrame.onCanvasUpdate(brushSize=self.parentCanvas.brushSize)
# }}}
# {{{ canvasIncrCanvasHeight(self, event): XXX
def canvasIncrCanvasHeight(self, event):
self.parentCanvas.resize([ \
self.parentCanvas.canvasSize[0], \
self.parentCanvas.canvasSize[1] + 1])
# }}}
# {{{ canvasIncrCanvasHeightWidth(self, event): XXX
def canvasIncrCanvasHeightWidth(self, event):
self.canvasIncrCanvasHeight(event)
self.canvasIncrCanvasWidth(event)
# }}}
# {{{ canvasIncrCanvasWidth(self, event): XXX
def canvasIncrCanvasWidth(self, event):
self.parentCanvas.resize([ \
self.parentCanvas.canvasSize[0] + 1, \
self.parentCanvas.canvasSize[1]])
# }}}
# {{{ canvasNew(self, event, newCanvasSize=None): XXX
def canvasNew(self, event, newCanvasSize=None):
if self.canvasPathName != None:
saveChanges = self._dialogSaveChanges()
if saveChanges == wx.ID_CANCEL:
return
elif saveChanges == wx.ID_NO:
pass
elif saveChanges == wx.ID_YES:
self.canvasSave(event)
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
if newCanvasSize == None:
newCanvasSize = list(self.parentCanvas.defaultCanvasSize)
self.parentCanvas.canvasImportStore.importNew(newCanvasSize)
self.canvasPathName = None
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
self.parentFrame.onCanvasUpdate(pathName="", undoLevel=-1)
# }}}
# {{{ canvasOpen(self, event): XXX
def canvasOpen(self, event):
if self.canvasPathName != None:
saveChanges = self._dialogSaveChanges()
if saveChanges == wx.ID_CANCEL:
return
elif saveChanges == wx.ID_NO:
pass
elif saveChanges == wx.ID_YES:
self.canvasSave(event)
with wx.FileDialog(self.parentCanvas, "Open", os.getcwd(), "", "mIRC art files (*.txt)|*.txt|All Files (*.*)|*.*", wx.FD_OPEN) as dialog:
if dialog.ShowModal() == wx.ID_CANCEL:
return False
else:
self.canvasPathName = dialog.GetPath()
print(self.canvasPathName)
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
self.parentCanvas.canvasImportStore.importTextFile(self.canvasPathName)
self.parentCanvas.canvasImportStore.importIntoPanel()
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
self.parentFrame.onCanvasUpdate( \
pathName=self.canvasPathName, undoLevel=-1)
return True
# }}}
# {{{ canvasPaste(self, event): XXX
def canvasPaste(self, event):
pass
# }}}
# {{{ canvasRedo(self, event): XXX
def canvasRedo(self, event):
self.parentCanvas._dispatchDeltaPatches( \
self.parentCanvas.canvasJournal.popRedo())
# }}}
# {{{ canvasSave(self, event): XXX
def canvasSave(self, event):
if self.canvasPathName == None:
if self.canvasSaveAs(event) == False:
return
try:
with open(self.canvasPathName, "w", encoding="utf-8") as outFile:
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
self.parentCanvas.canvasExportStore.exportTextFile( \
self.parentCanvas.canvasMap, \
self.parentCanvas.canvasSize, outFile)
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
return True
except IOError as error:
return False
# }}}
# {{{ canvasSaveAs(self, event): XXX
def canvasSaveAs(self, event):
with wx.FileDialog(self.parentCanvas, "Save As", os.getcwd(), "", "mIRC art files (*.txt)|*.txt|All Files (*.*)|*.*", wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) as dialog:
if dialog.ShowModal() == wx.ID_CANCEL:
return False
else:
self.canvasPathName = dialog.GetPath()
return self.canvasSave(event)
# }}} # }}}
# {{{ canvasToolCircle(self, event): XXX # {{{ canvasToolCircle(self, event): XXX
def canvasToolCircle(self, event): def canvasToolCircle(self, event):
self.canvasTool = ToolCircle(self.parentCanvas) self.canvasTool = ToolCircle(self.parentCanvas)
@ -417,11 +419,6 @@ class GuiCanvasInterface():
toolBar.ToggleTool(self.parentFrame.CID_TEXT[0], True) toolBar.ToggleTool(self.parentFrame.CID_TEXT[0], True)
self.parentFrame.onCanvasUpdate(toolName=self.canvasTool.name) self.parentFrame.onCanvasUpdate(toolName=self.canvasTool.name)
# }}} # }}}
# {{{ canvasUndo(self, event): XXX
def canvasUndo(self, event):
self.parentCanvas._dispatchDeltaPatches( \
self.parentCanvas.canvasJournal.popUndo())
# }}}
# #
# __init__(self, parentCanvas, parentFrame): # __init__(self, parentCanvas, parentFrame):

View File

@ -180,7 +180,7 @@ class GuiFrame(GuiGeneralFrame):
textItems.append("Current tool: {}".format( \ textItems.append("Current tool: {}".format( \
self.lastPanelState["toolName"])) self.lastPanelState["toolName"]))
self.statusBar.SetStatusText(" | ".join(textItems)) self.statusBar.SetStatusText(" | ".join(textItems))
if "undoLevel" in self.lastPanelState: if "undoLevel" in self.lastPanelState:
if self.lastPanelState["undoLevel"] >= 0: if self.lastPanelState["undoLevel"] >= 0:
self.menuItemsById[self.CID_UNDO[0]].Enable(True) self.menuItemsById[self.CID_UNDO[0]].Enable(True)
toolBar = self.toolBarItemsById[self.CID_UNDO[0]].GetToolBar() toolBar = self.toolBarItemsById[self.CID_UNDO[0]].GetToolBar()

View File

@ -28,7 +28,7 @@ class ToolRect(Tool):
patch = [atPoint[0] + brushCol, atPoint[1] + brushRow, *brushColours, 0, " "] patch = [atPoint[0] + brushCol, atPoint[1] + brushRow, *brushColours, 0, " "]
if isLeftDown or isRightDown: if isLeftDown or isRightDown:
dispatchFn(eventDc, False, patch); dispatchFn(eventDc, True, patch); dispatchFn(eventDc, False, patch); dispatchFn(eventDc, True, patch);
else: else:
dispatchFn(eventDc, True, patch) dispatchFn(eventDc, True, patch)
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 # vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -19,9 +19,12 @@ def main(*argv):
if len(argv) > 1 \ if len(argv) > 1 \
and len(argv[1]) > 0: and len(argv[1]) > 0:
appFrame.panelCanvas.canvasInterface.canvasPathName = argv[1] appFrame.panelCanvas.canvasInterface.canvasPathName = argv[1]
appFrame.panelCanvas.canvasImportStore.importTextFile(argv[1]) rc, error = appFrame.panelCanvas.canvasImportStore.importTextFile(argv[1])
appFrame.panelCanvas.canvasImportStore.importIntoPanel() if rc:
appFrame.onCanvasUpdate(pathName=argv[1], undoLevel=-1) appFrame.panelCanvas.onStoreUpdate(appFrame.panelCanvas.canvasImportStore.inSize, appFrame.panelCanvas.canvasImportStore.outMap)
appFrame.onCanvasUpdate(pathName=argv[1], undoLevel=-1)
else:
print("error: {}".format(error), file=sys.stderr)
wxApp.MainLoop() wxApp.MainLoop()
if __name__ == "__main__": if __name__ == "__main__":
main(*sys.argv) main(*sys.argv)