mirror of
https://github.com/lalbornoz/roar.git
synced 2024-11-21 23:06:38 +00:00
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:
parent
bb4ba3ae46
commit
34d9df756b
@ -12,8 +12,7 @@ from CanvasImportStore import CanvasImportStore
|
||||
import sys
|
||||
|
||||
def reduce(inPathName):
|
||||
canvasStore = CanvasImportStore(inPathName)
|
||||
inMap = canvasStore.outMap.copy(); del canvasStore;
|
||||
canvasStore = CanvasImportStore(inPathName); inMap = canvasStore.outMap.copy();
|
||||
with open(inPathName, "w+") as outFile:
|
||||
for inCurRow in range(len(inMap)):
|
||||
lastAttribs, lastColours = CanvasImportStore._CellState.CS_NONE, None
|
||||
@ -25,15 +24,21 @@ def reduce(inPathName):
|
||||
if inCurCell[2] & CanvasImportStore._CellState.CS_UNDERLINE:
|
||||
print("\u001f", end="", file=outFile)
|
||||
lastAttribs = inCurCell[2]
|
||||
if lastColours == None \
|
||||
or (lastColours[0] != inCurCell[:2][0] \
|
||||
and lastColours[1] != inCurCell[:2][1]):
|
||||
print("\u0003{:d},{:d}{}".format(*inCurCell[:2], inCurCell[3]), end="", file=outFile)
|
||||
if lastColours == None \
|
||||
or (lastColours[0] != inCurCell[:2][0] \
|
||||
and lastColours[1] != inCurCell[:2][1]):
|
||||
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]
|
||||
elif lastColours[1] == inCurCell[:2][1] \
|
||||
and lastColours[0] != inCurCell[:2][0]:
|
||||
print("\u0003{:d}{}".format(inCurCell[:2][0], inCurCell[3]), end="", file=outFile)
|
||||
lastColours[0] = inCurCell[:2][0]
|
||||
elif (lastColours[1] == inCurCell[:2][1]) \
|
||||
and (lastColours[0] != inCurCell[:2][0]):
|
||||
if (inCurCell[3] in set("0123456789")) and (inCurCell[0] < 10):
|
||||
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:
|
||||
print(inCurCell[3], end="", file=outFile)
|
||||
print("\n", end="", file=outFile)
|
||||
|
@ -18,9 +18,12 @@ def main(*argv):
|
||||
print("usage: {} <MiRCART input file pathname>".format(sys.argv[0]), file=sys.stderr)
|
||||
else:
|
||||
canvasImportStore = CanvasImportStore()
|
||||
canvasImportStore.importAnsiFile(argv[1])
|
||||
canvasExportStore = CanvasExportStore()
|
||||
canvasExportStore.exportAnsiFile(canvasImportStore.outMap, canvasImportStore.inSize, sys.stdout)
|
||||
rc, error = canvasImportStore.importAnsiFile(argv[1])
|
||||
if rc:
|
||||
canvasExportStore = CanvasExportStore()
|
||||
canvasExportStore.exportAnsiFile(canvasImportStore.outMap, canvasImportStore.inSize, sys.stdout)
|
||||
else
|
||||
print("error: {}".format(error), file=sys.stderr)
|
||||
if __name__ == "__main__":
|
||||
main(*sys.argv)
|
||||
|
||||
|
@ -27,9 +27,12 @@ def main(*argv):
|
||||
optdict["-s"] = 11 if not "-s" in optdict else int(optdict["-s"])
|
||||
for inFile in argv:
|
||||
canvasImportStore = CanvasImportStore()
|
||||
canvasImportStore.importTextFile(inFile)
|
||||
canvasExportStore = CanvasExportStore()
|
||||
canvasExportStore.exportPngFile(canvasImportStore.outMap, os.path.splitext(inFile)[0] + ".png", optdict["-f"], optdict["-s"])
|
||||
rc, error = canvasImportStore.importTextFile(inFile)
|
||||
if rc:
|
||||
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__":
|
||||
main(*sys.argv)
|
||||
|
||||
|
@ -18,10 +18,13 @@ def main(*argv):
|
||||
print("usage: {} <SAUCE input file pathname> <ANSI output file pathname>".format(sys.argv[0]), file=sys.stderr)
|
||||
else:
|
||||
canvasImportStore = CanvasImportStore()
|
||||
canvasImportStore.importSauceFile(argv[1])
|
||||
canvasExportStore = CanvasExportStore()
|
||||
with open(argv[2], "w", encoding="utf-8") as outFile:
|
||||
canvasExportStore.exportAnsiFile(canvasImportStore.outMap, canvasImportStore.inSize, outFile)
|
||||
rc, error = canvasImportStore.importSauceFile(argv[1])
|
||||
if rc:
|
||||
canvasExportStore = CanvasExportStore()
|
||||
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__":
|
||||
main(*sys.argv)
|
||||
|
||||
|
@ -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)
|
||||
else:
|
||||
canvasImportStore = CanvasImportStore()
|
||||
canvasImportStore.importSauceFile(argv[1])
|
||||
canvasExportStore = CanvasExportStore()
|
||||
with open(argv[2], "w", encoding="utf-8") as outFile:
|
||||
canvasExportStore.exportTextFile(canvasImportStore.outMap, canvasImportStore.inSize, outFile)
|
||||
rc, error = canvasImportStore.importSauceFile(argv[1])
|
||||
if rc:
|
||||
canvasExportStore = CanvasExportStore()
|
||||
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__":
|
||||
main(*sys.argv)
|
||||
|
||||
|
@ -43,7 +43,7 @@ class Canvas(wx.Panel):
|
||||
if commitUndo:
|
||||
if not self._canvasDirty:
|
||||
self.canvasJournal.pushDeltas([], []); self._canvasDirty = True;
|
||||
self.canvasJournal.updateCurrentDeltas(patchDelta, patch)
|
||||
self.canvasJournal.updateCurrentDeltas(patch, patchDelta)
|
||||
self._commitPatch(patch)
|
||||
# }}}
|
||||
|
||||
@ -90,7 +90,7 @@ class Canvas(wx.Panel):
|
||||
# }}}
|
||||
# {{{ onPanelPaint(self, event): XXX
|
||||
def onPanelPaint(self, event):
|
||||
self.canvasBackend.onPanelPaintEvent(self, event)
|
||||
self.canvasBackend.onPanelPaintEvent(event, self)
|
||||
# }}}
|
||||
# {{{ onStoreUpdate(self, newCanvasSize, newCanvas=None): XXX
|
||||
def onStoreUpdate(self, newCanvasSize, newCanvas=None):
|
||||
@ -129,7 +129,7 @@ class Canvas(wx.Panel):
|
||||
undoPatches, redoPatches = ["resize", *oldCanvasSize], ["resize", *newCanvasSize]
|
||||
if not self._canvasDirty:
|
||||
self.canvasJournal.pushDeltas([], []); self._canvasDirty = True;
|
||||
self.canvasJournal.updateCurrentDeltas(undoPatches, redoPatches)
|
||||
self.canvasJournal.updateCurrentDeltas(redoPatches, undoPatches)
|
||||
|
||||
if deltaCanvasSize[0] < 0:
|
||||
for numRow in range(oldCanvasSize[1]):
|
||||
@ -137,7 +137,7 @@ class Canvas(wx.Panel):
|
||||
for numCol in range((oldCanvasSize[0] + deltaCanvasSize[0]), oldCanvasSize[0]):
|
||||
if not self._canvasDirty:
|
||||
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]
|
||||
else:
|
||||
for numRow in range(oldCanvasSize[1]):
|
||||
@ -150,7 +150,7 @@ class Canvas(wx.Panel):
|
||||
for numCol in range(oldCanvasSize[0] + deltaCanvasSize[0]):
|
||||
if not self._canvasDirty:
|
||||
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]
|
||||
else:
|
||||
for numNewRow in range(oldCanvasSize[1], newCanvasSize[1]):
|
||||
@ -182,7 +182,7 @@ class Canvas(wx.Panel):
|
||||
self.canvasBackend = CanvasBackend(defaultCanvasSize, defaultCellSize)
|
||||
self.canvasJournal = CanvasJournal()
|
||||
self.canvasExportStore = CanvasExportStore()
|
||||
self.canvasImportStore = CanvasImportStore(parentCanvas=self)
|
||||
self.canvasImportStore = CanvasImportStore()
|
||||
self.canvasInterface = canvasInterface(self, parentFrame)
|
||||
|
||||
# Bind event handlers
|
||||
|
@ -13,81 +13,59 @@ class CanvasBackend():
|
||||
# {{{ _drawBrushPatch(self, eventDc, patch): XXX
|
||||
def _drawBrushPatch(self, eventDc, patch):
|
||||
absPoint = self._xlatePoint(patch)
|
||||
brushFg = self._brushes[patch[3]]
|
||||
brushBg = self._brushes[patch[2]]
|
||||
pen = self._pens[patch[3]]
|
||||
brushBg, brushFg, pen = self._brushes[patch[2]], self._brushes[patch[3]], self._pens[patch[3]]
|
||||
self._setBrushDc(brushBg, brushFg, eventDc, pen)
|
||||
eventDc.DrawRectangle(*absPoint, *self.cellSize)
|
||||
# }}}
|
||||
# {{{ _drawCharPatch(self, eventDc, patch): XXX
|
||||
def _drawCharPatch(self, eventDc, patch):
|
||||
absPoint = self._xlatePoint(patch)
|
||||
brushFg = self._brushes[patch[2]]
|
||||
brushBg = self._brushes[patch[3]]
|
||||
pen = self._pens[patch[3]]
|
||||
fontBitmap = wx.Bitmap(*self.cellSize)
|
||||
absPoint, fontBitmap = self._xlatePoint(patch), wx.Bitmap(*self.cellSize)
|
||||
brushBg, brushFg, pen = self._brushes[patch[3]], self._brushes[patch[2]], self._pens[patch[3]]
|
||||
fontDc = wx.MemoryDC(); fontDc.SelectObject(fontBitmap);
|
||||
fontDc.SetTextForeground(wx.Colour(Colours[patch[2]][0:4]))
|
||||
fontDc.SetTextBackground(wx.Colour(Colours[patch[3]][0:4]))
|
||||
fontDc.SetTextForeground(wx.Colour(Colours[patch[2]][:4]))
|
||||
fontDc.SetTextBackground(wx.Colour(Colours[patch[3]][:4]))
|
||||
fontDc.SetBrush(brushBg); fontDc.SetBackground(brushBg); fontDc.SetPen(pen);
|
||||
fontDc.SetFont(self._font)
|
||||
fontDc.DrawRectangle(0, 0, *self.cellSize)
|
||||
fontDc.DrawText(patch[5], 0, 0)
|
||||
fontDc.DrawRectangle(0, 0, *self.cellSize); fontDc.DrawText(patch[5], 0, 0);
|
||||
eventDc.Blit(*absPoint, *self.cellSize, fontDc, 0, 0)
|
||||
# }}}
|
||||
# {{{ _finiBrushesAndPens(self): XXX
|
||||
def _finiBrushesAndPens(self):
|
||||
for brush in self._brushes or []:
|
||||
brush.Destroy()
|
||||
self._brushes = None
|
||||
for pen in self._pens or []:
|
||||
pen.Destroy()
|
||||
self._pens = None
|
||||
self._lastBrushBg = self._lastBrushFg = self._lastPen = None;
|
||||
[brush.Destroy() for brush in self._brushes or []]
|
||||
[pen.Destroy() for pen in self._pens or []]
|
||||
self._brushes, self._lastBrushBg, self._lastBrushFg, self._lastPen, self._pens = None, None, None, None, None
|
||||
# }}}
|
||||
# {{{ _initBrushesAndPens(self): XXX
|
||||
def _initBrushesAndPens(self):
|
||||
self._brushes = [None for x in range(len(Colours))]
|
||||
self._pens = [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))]
|
||||
for mircColour in range(len(Colours)):
|
||||
self._brushes[mircColour] = wx.Brush( \
|
||||
wx.Colour(Colours[mircColour][0:4]), wx.BRUSHSTYLE_SOLID)
|
||||
self._pens[mircColour] = wx.Pen( \
|
||||
wx.Colour(Colours[mircColour][0:4]), 1)
|
||||
self._lastBrushBg = self._lastBrushFg = self._lastPen = None;
|
||||
self._brushes[mircColour] = wx.Brush(wx.Colour(Colours[mircColour][:4]), wx.BRUSHSTYLE_SOLID)
|
||||
self._pens[mircColour] = wx.Pen(wx.Colour(Colours[mircColour][:4]), 1)
|
||||
self._lastBrushBg, self._lastBrushFg, self._lastPen = None, None, None
|
||||
# }}}
|
||||
# {{{ _setBrushDc(self, brushBg, brushFg, dc, pen): XXX
|
||||
def _setBrushDc(self, brushBg, brushFg, dc, pen):
|
||||
if self._lastBrushBg != brushBg:
|
||||
dc.SetBackground(brushBg)
|
||||
self._lastBrushBg = brushBg
|
||||
dc.SetBackground(brushBg); self._lastBrushBg = brushBg;
|
||||
if self._lastBrushFg != brushFg:
|
||||
dc.SetBrush(brushFg)
|
||||
self._lastBrushFg = brushFg
|
||||
dc.SetBrush(brushFg); self._lastBrushFg = brushFg;
|
||||
if self._lastPen != pen:
|
||||
dc.SetPen(pen)
|
||||
self._lastPen = pen
|
||||
dc.SetPen(pen); self._lastPen = pen;
|
||||
# }}}
|
||||
# {{{ _xlatePoint(self, patch): XXX
|
||||
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
|
||||
def drawCursorMaskWithJournal(self, canvasJournal, eventDc):
|
||||
for patch in canvasJournal.popCursor():
|
||||
self.drawPatch(eventDc, patch)
|
||||
[self.drawPatch(eventDc, patch) for patch in canvasJournal.popCursor()]
|
||||
# }}}
|
||||
# {{{ drawPatch(self, eventDc, patch): XXX
|
||||
def drawPatch(self, eventDc, patch):
|
||||
if patch[0] < self.canvasSize[0] \
|
||||
and patch[0] >= 0 \
|
||||
and patch[1] < self.canvasSize[1] \
|
||||
and patch[1] >= 0:
|
||||
if patch[5] == " ":
|
||||
self._drawBrushPatch(eventDc, patch)
|
||||
else:
|
||||
self._drawCharPatch(eventDc, patch)
|
||||
if ((patch[0] >= 0) and (patch[0] < self.canvasSize[0])) \
|
||||
and ((patch[1] >= 0) and (patch[1] < self.canvasSize[1])):
|
||||
self._drawBrushPatch(eventDc, patch) if patch[5] == " " else self._drawCharPatch(eventDc, patch)
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
@ -95,11 +73,11 @@ class CanvasBackend():
|
||||
# {{{ getDeviceContext(self, parentWindow): XXX
|
||||
def getDeviceContext(self, parentWindow):
|
||||
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
|
||||
# }}}
|
||||
# {{{ onPanelPaintEvent(self, panelWindow, panelEvent): XXX
|
||||
def onPanelPaintEvent(self, panelWindow, panelEvent):
|
||||
# {{{ onPanelPaintEvent(self, panelEvent, panelWindow): XXX
|
||||
def onPanelPaintEvent(self, panelEvent, panelWindow):
|
||||
if self.canvasBitmap != None:
|
||||
eventDc = wx.BufferedPaintDC(panelWindow, self.canvasBitmap)
|
||||
# }}}
|
||||
@ -113,27 +91,19 @@ class CanvasBackend():
|
||||
if self.canvasBitmap == None:
|
||||
self.canvasBitmap = wx.Bitmap(winSize)
|
||||
else:
|
||||
oldDc = wx.MemoryDC()
|
||||
oldDc.SelectObject(self.canvasBitmap)
|
||||
newDc = wx.MemoryDC()
|
||||
newBitmap = wx.Bitmap(winSize)
|
||||
newDc.SelectObject(newBitmap)
|
||||
oldDc = wx.MemoryDC(); oldDc.SelectObject(self.canvasBitmap);
|
||||
newDc = wx.MemoryDC(); newBitmap = wx.Bitmap(winSize); newDc.SelectObject(newBitmap);
|
||||
newDc.Blit(0, 0, *self.canvasBitmap.GetSize(), oldDc, 0, 0)
|
||||
oldDc.SelectObject(wx.NullBitmap)
|
||||
self.canvasBitmap.Destroy(); self.canvasBitmap = newBitmap;
|
||||
self.canvasSize = canvasSize; self.cellSize = cellSize;
|
||||
self._font = wx.Font( \
|
||||
8, \
|
||||
wx.FONTFAMILY_TELETYPE, \
|
||||
wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
|
||||
self.canvasSize, self.cellSize = canvasSize, cellSize
|
||||
self._font = wx.Font(8, wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
|
||||
# }}}
|
||||
# {{{ xlateEventPoint(self, event, eventDc): XXX
|
||||
def xlateEventPoint(self, event, eventDc):
|
||||
eventPoint = event.GetLogicalPosition(eventDc)
|
||||
rectX = eventPoint.x - (eventPoint.x % self.cellSize[0])
|
||||
rectY = eventPoint.y - (eventPoint.y % self.cellSize[1])
|
||||
mapX = int(rectX / self.cellSize[0] if rectX else 0)
|
||||
mapY = int(rectY / self.cellSize[1] if rectY else 0)
|
||||
rectX, rectY = eventPoint.x - (eventPoint.x % self.cellSize[0]), 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)
|
||||
return (mapX, mapY)
|
||||
# }}}
|
||||
|
||||
@ -149,7 +119,6 @@ class CanvasBackend():
|
||||
def __init__(self, canvasSize, cellSize):
|
||||
self._brushes, self._font, self._lastBrush, self._lastPen, self._pens = None, None, None, None, None
|
||||
self.canvasBitmap, self.cellSize = None, None
|
||||
self._initBrushesAndPens()
|
||||
self.reset(canvasSize, cellSize)
|
||||
self._initBrushesAndPens(); self.reset(canvasSize, cellSize);
|
||||
|
||||
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
||||
|
@ -31,38 +31,19 @@ class CanvasExportStore():
|
||||
ImgurUploadUrl = "https://api.imgur.com/3/upload.json"
|
||||
PastebinPostUrl = "https://pastebin.com/api/api_post.php"
|
||||
|
||||
# {{{ _drawUnderline(self, curPos, fontSize, imgDraw, fillColour): XXX
|
||||
def _drawUnderLine(self, curPos, fontSize, imgDraw, fillColour):
|
||||
# {{{ _drawUnderline(self, curPos, fillColour, fontSize, imgDraw): XXX
|
||||
def _drawUnderLine(self, curPos, fillColour, fontSize, imgDraw):
|
||||
imgDraw.line( \
|
||||
xy=(curPos[0], curPos[1] + (fontSize[1] - 2), \
|
||||
curPos[0] + fontSize[0], curPos[1] + (fontSize[1] - 2)), \
|
||||
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
|
||||
def exportAnsiFile(self, canvasMap, canvasSize, outFile):
|
||||
outBuffer = ""
|
||||
for inCurRow in range(len(canvasMap)):
|
||||
lastAttribs = self._CellState.CS_NONE
|
||||
lastColours = None
|
||||
lastAttribs, lastColours = self._CellState.CS_NONE, None
|
||||
for inCurCol in range(len(canvasMap[inCurRow])):
|
||||
inCurCell = canvasMap[inCurRow][inCurCol]
|
||||
if lastAttribs != inCurCell[2]:
|
||||
@ -79,14 +60,32 @@ class CanvasExportStore():
|
||||
else:
|
||||
outBuffer += inCurCell[3]
|
||||
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
|
||||
def exportBitmapToImgur(self, apiKey, canvasBitmap, imgName, imgTitle, imgType):
|
||||
tmpPathName = tempfile.mkstemp()
|
||||
os.close(tmpPathName[0])
|
||||
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])
|
||||
return imgurResult
|
||||
# }}}
|
||||
@ -107,39 +106,32 @@ class CanvasExportStore():
|
||||
"api_paste_private": pastePrivate}
|
||||
responseHttp = requests.post(self.PastebinPostUrl, data=requestData)
|
||||
if responseHttp.status_code == 200:
|
||||
if responseHttp.text.startswith("http"):
|
||||
return (True, responseHttp.text)
|
||||
else:
|
||||
return (False, responseHttp.text)
|
||||
return (True if responseHttp.text.startswith("http") else False, responseHttp.text)
|
||||
else:
|
||||
return (False, str(responseHttp.status_code))
|
||||
else:
|
||||
return (False, "missing requests and/or urllib3 module(s)")
|
||||
# }}}
|
||||
# {{{ exportPngFile(self, canvasMap, outPathName, fontFilePath, fontSize): XXX
|
||||
def exportPngFile(self, canvasMap, outPathName, fontFilePath, fontSize):
|
||||
# {{{ exportPngFile(self, canvasMap, fontFilePath, fontSize, outPathName): XXX
|
||||
def exportPngFile(self, canvasMap, fontFilePath, fontSize, outPathName):
|
||||
if havePIL:
|
||||
inSize = (len(canvasMap[0]), len(canvasMap))
|
||||
outCurPos = [0, 0]
|
||||
outFontFilePath, outFontSize = fontFilePath, fontSize
|
||||
outImgFont = ImageFont.truetype(outFontFilePath, outFontSize)
|
||||
outImgFontSize = [*outImgFont.getsize(" ")]
|
||||
outImgFontSize[1] += 3
|
||||
inSize = (len(canvasMap[0]), len(canvasMap))
|
||||
outSize = [a*b for a,b in zip(inSize, outImgFontSize)]
|
||||
outCurPos = [0, 0]
|
||||
outImgFontSize = [*outImgFont.getsize(" ")]; outImgFontSize[1] += 3;
|
||||
outSize = [a * b for a, b in zip(inSize, outImgFontSize)]
|
||||
outImg = Image.new("RGBA", outSize, (*ColourMapNormal[1], 255))
|
||||
outImgDraw = ImageDraw.Draw(outImg)
|
||||
outImgDraw.fontmode = "1"
|
||||
outImgDraw = ImageDraw.Draw(outImg); outImgDraw.fontmode = "1";
|
||||
for inCurRow in range(len(canvasMap)):
|
||||
for inCurCol in range(len(canvasMap[inCurRow])):
|
||||
inCurCell = canvasMap[inCurRow][inCurCol]
|
||||
outColours = [0, 0]
|
||||
inCurCell = canvasMap[inCurRow][inCurCol]; outColours = (0, 0);
|
||||
if inCurCell[2] & self._CellState.CS_BOLD:
|
||||
if inCurCell[3] != " ":
|
||||
if inCurCell[3] == "█":
|
||||
outColours[1] = ColourMapNormal[inCurCell[0]]
|
||||
else:
|
||||
outColours[0] = ColourMapBold[inCurCell[0]]
|
||||
outColours[1] = ColourMapNormal[inCurCell[1]]
|
||||
outColours = (ColourMapBold[inCurCell[0]], ColourMapNormal[inCurCell[1]])
|
||||
else:
|
||||
outColours[1] = ColourMapNormal[inCurCell[1]]
|
||||
else:
|
||||
@ -147,8 +139,7 @@ class CanvasExportStore():
|
||||
if inCurCell[3] == "█":
|
||||
outColours[1] = ColourMapNormal[inCurCell[0]]
|
||||
else:
|
||||
outColours[0] = ColourMapNormal[inCurCell[0]]
|
||||
outColours[1] = ColourMapNormal[inCurCell[1]]
|
||||
outColours = (ColourMapNormal[inCurCell[0]], ColourMapNormal[inCurCell[1]])
|
||||
else:
|
||||
outColours[1] = ColourMapNormal[inCurCell[1]]
|
||||
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)
|
||||
if inCurCell[2] & self._CellState.CS_UNDERLINE:
|
||||
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] = 0
|
||||
outCurPos[1] += outImgFontSize[1]
|
||||
outCurPos[0] = 0; outCurPos[1] += outImgFontSize[1];
|
||||
outImg.save(outPathName);
|
||||
return True
|
||||
return (True, None)
|
||||
else:
|
||||
return False
|
||||
return (False, "missing PIL modules")
|
||||
# }}}
|
||||
# {{{ exportTextBuffer(self, canvasMap, canvasSize): XXX
|
||||
def exportTextBuffer(self, canvasMap, canvasSize):
|
||||
@ -191,12 +181,15 @@ class CanvasExportStore():
|
||||
canvasLastColours[0] = canvasColColours[0]
|
||||
outBuffer += canvasColText
|
||||
outBuffer += "\n"
|
||||
return outBuffer
|
||||
if len(outBuffer):
|
||||
return (True, outBuffer)
|
||||
else:
|
||||
return (False, "empty buffer generated")
|
||||
# }}}
|
||||
# {{{ exportTextFile(self, canvasMap, canvasSize, outFile): XXX
|
||||
def exportTextFile(self, canvasMap, canvasSize, outFile):
|
||||
outBuffer = self.exportTextBuffer(canvasMap, canvasSize)
|
||||
outFile.write(outBuffer)
|
||||
rc, outBuffer = self.exportTextBuffer(canvasMap, canvasSize)
|
||||
return outFile.write(outBuffer) if rc else (rc, outBuffer)
|
||||
# }}}
|
||||
|
||||
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
||||
|
@ -17,271 +17,129 @@ class CanvasImportStore():
|
||||
CS_ITALIC = 0x02
|
||||
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
|
||||
def _flipCellStateBit(self, cellState, bit):
|
||||
# {{{ _flipCellStateBit(self, bit, cellState): XXX
|
||||
def _flipCellStateBit(self, bit, cellState):
|
||||
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
|
||||
def importAnsiFile(self, inPathName, encoding="cp437"):
|
||||
return self.importAnsiFileBuffer(open(inPathName, "rb"), encoding)
|
||||
# }}}
|
||||
# {{{ importAnsiFileBuffer(self, inFile, encoding="cp437"): XXX
|
||||
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
|
||||
# {{{ importAnsiBuffer(self, inFile, encoding="cp437", width=None): XXX
|
||||
def importAnsiBuffer(self, inFile, encoding="cp437", width=None):
|
||||
curBg, curBgAnsi, curBoldAnsi, curFg, curFgAnsi = 1, 30, False, 15, 37
|
||||
done, outMap, outMaxCols = False, [[]], 0
|
||||
inFileData = inFile.read().decode(encoding)
|
||||
inFileChar, inFileCharMax = 0, len(inFileData)
|
||||
curBg, curFg, done, inCurRow = 1, 15, False, 0; curBgAnsi, curBoldAnsi, curFgAnsi = 30, False, 37;
|
||||
while True:
|
||||
if inFileChar >= inFileCharMax:
|
||||
break
|
||||
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:
|
||||
newBg, newFg = -1, -1
|
||||
for ansiCode in m[1].split(";"):
|
||||
ansiCode = int(ansiCode)
|
||||
if ansiCode == 0:
|
||||
curBgAnsi, curBoldAnsi, curFgAnsi = 30, False, 37; newBg, newFg = 1, 15;
|
||||
elif ansiCode == 1:
|
||||
curBoldAnsi, newFg = True, AnsiFgBoldToMiRCARTColours[curFgAnsi]
|
||||
elif ansiCode == 2:
|
||||
curBoldAnsi, newFg = False, AnsiFgToMiRCARTColours[curFgAnsi]
|
||||
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
|
||||
if m[1][-1] == "C":
|
||||
outMap[-1] += [[curFg, curBg, self._CellState.CS_NONE, " "]] * int(m[1][:-1])
|
||||
elif m[1][-1] == "m":
|
||||
newBg, newFg = -1, -1
|
||||
for ansiCode in [int(c) for c in m[1][:-1].split(";")]:
|
||||
if ansiCode == 0:
|
||||
curBgAnsi, curBoldAnsi, curFgAnsi, newBg, newFg = 30, False, 37, 1, 15
|
||||
elif ansiCode == 1:
|
||||
curBoldAnsi, newFg = True, AnsiFgBoldToMiRCARTColours[curFgAnsi]
|
||||
elif ansiCode == 2:
|
||||
curBoldAnsi, newFg = False, AnsiFgToMiRCARTColours[curFgAnsi]
|
||||
elif ansiCode == 7:
|
||||
curBgAnsi, curFgAnsi, newBg, newFg = curFgAnsi, curBgAnsi, curFg, curBg
|
||||
elif ansiCode in AnsiBgToMiRCARTColours:
|
||||
curBgAnsi, newBg = ansiCode, AnsiBgToMiRCARTColours[ansiCode]
|
||||
elif ansiCode in AnsiFgBoldToMiRCARTColours:
|
||||
curFgAnsi, newFg = ansiCode, AnsiFgBoldToMiRCARTColours[ansiCode]
|
||||
elif ansiCode in AnsiFgToMiRCARTColours:
|
||||
newFg = AnsiFgBoldToMiRCARTColours[ansiCode] if curBoldAnsi else AnsiFgToMiRCARTColours[ansiCode]
|
||||
curFgAnsi = ansiCode
|
||||
curBg = newBg if newBg != -1 else curBg; curFg = newFg if newFg != -1 else curFg;
|
||||
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:
|
||||
m = re.match('\x1b\[(\d+)C', inFileData[inFileChar:])
|
||||
if m:
|
||||
for numRepeat in range(int(m[1])):
|
||||
outMap[inCurRow].append([curFg, curBg, self._CellState.CS_NONE, " "])
|
||||
inFileChar += len(m[0])
|
||||
elif inFileData[inFileChar:inFileChar+2] == "\r\n":
|
||||
inFileChar += 2; done = True;
|
||||
elif inFileData[inFileChar] == "\r" \
|
||||
or inFileData[inFileChar] == "\n":
|
||||
inFileChar += 1; done = True;
|
||||
else:
|
||||
outMap[inCurRow].append([curFg, curBg, self._CellState.CS_NONE, inFileData[inFileChar]])
|
||||
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
|
||||
outMap[-1].append([curFg, curBg, self._CellState.CS_NONE, inFileData[inFileChar]])
|
||||
inFileChar += 1
|
||||
if done or (width == len(outMap[-1])):
|
||||
done, outMaxCols, = False, max(outMaxCols, len(outMap[-1])); outMap.append([]);
|
||||
if len(outMap[0]):
|
||||
for numRow in range(len(outMap)):
|
||||
for numCol in range(len(outMap[numRow]), outMaxCols):
|
||||
outMap[numRow].append([curFg, curBg, self._CellState.CS_NONE, " "])
|
||||
self.inSize, self.outMap = [outMaxCols, len(outMap)], outMap
|
||||
return (True, None)
|
||||
else:
|
||||
return (False, "empty output map")
|
||||
# }}}
|
||||
# {{{ importIntoPanel(self): XXX
|
||||
def importIntoPanel(self):
|
||||
self.parentCanvas.onStoreUpdate(self.inSize, self.outMap)
|
||||
# }}}
|
||||
# {{{ 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)
|
||||
# {{{ importAnsiFile(self, inPathName, encoding="cp437"): XXX
|
||||
def importAnsiFile(self, inPathName, encoding="cp437"):
|
||||
return self.importAnsiBuffer(open(inPathName, "rb"), encoding)
|
||||
# }}}
|
||||
# {{{ importSauceFile(self, inPathName): XXX
|
||||
def importSauceFile(self, inPathName):
|
||||
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(5 + 2 + 35 + 20 + 20 + 8 + 4, 1)
|
||||
if (inFile.read(1) == b'\x01') \
|
||||
and (inFile.read(1) == b'\x01'):
|
||||
width, height = struct.unpack("H", inFile.read(2))[0], struct.unpack("H", inFile.read(2))[0]
|
||||
inFile.seek(0, 0)
|
||||
inFileData, row, rowChars = inFile.read(inFileStat.st_size - 128).decode("cp437"), "", 0
|
||||
inFileChar, inFileCharMax = 0, len(inFileData)
|
||||
curBg, curFg, inCurRow = 1, 15, 0; curBgAnsi, curBoldAnsi, curFgAnsi = 30, False, 37;
|
||||
while True:
|
||||
if inFileChar >= inFileCharMax:
|
||||
break
|
||||
else:
|
||||
m = re.match('\x1b\[((?:\d{1,3};?)+)m', inFileData[inFileChar:])
|
||||
if m:
|
||||
newBg, newFg = -1, -1
|
||||
for ansiCode in m[1].split(";"):
|
||||
ansiCode = int(ansiCode)
|
||||
if ansiCode == 0:
|
||||
curBgAnsi, curBoldAnsi, curFgAnsi = 30, False, 37; newBg, newFg = 1, 15;
|
||||
elif ansiCode == 1:
|
||||
curBoldAnsi, newFg = True, AnsiFgBoldToMiRCARTColours[curFgAnsi]
|
||||
elif ansiCode == 2:
|
||||
curBoldAnsi, newFg = False, AnsiFgToMiRCARTColours[curFgAnsi]
|
||||
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])
|
||||
inFileStat = os.stat(inPathName); inFile.seek(inFileStat.st_size - 128, 0); inFile.seek(94);
|
||||
if inFile.read(2) == b'\x01\x01':
|
||||
width = struct.unpack("H", inFile.read(2))[0]
|
||||
inFile.seek(0, 0); inFileData = inFile.read(inFileStat.st_size - 128);
|
||||
return self.importAnsiFileBuffer(io.StringIO(inFileData), width)
|
||||
else:
|
||||
return (False, "only character based ANSi SAUCE files are supported")
|
||||
# }}}
|
||||
# {{{ importTextBuffer(self, inFile): XXX
|
||||
def importTextBuffer(self, inFile):
|
||||
inLine, outMap, outMaxCols = inFile.readline(), [], 0
|
||||
while inLine:
|
||||
inCellState, inCurCol, inCurColours, inMaxCol = self._CellState.CS_NONE, 0, (15, 1), len(inLine); outMap.append([]);
|
||||
while inCurCol < inMaxCol:
|
||||
inChar = inLine[inCurCol]
|
||||
if inChar in set("\r\n"):
|
||||
inCurCol += 1
|
||||
elif inChar == "\u0002":
|
||||
inCellState = self._flipCellStateBit(self._CellState.CS_BOLD, inCellState); inCurCol += 1;
|
||||
elif inChar == "\u0003":
|
||||
m = re.match("\u0003((1[0-5]|0?[0-9])?(?:,(1[0-5]|0?[0-9]))?)", inLine[inCurCol:])
|
||||
if m:
|
||||
if (m[2] != None) and (m[3] != None):
|
||||
inCurColours = (int(m[2]), int(m[3]))
|
||||
elif (m[2] == None) and (m[3] != None):
|
||||
inCurColours = (int(m[2]), int(curColours[1]))
|
||||
else:
|
||||
m = re.match('\x1b\[(\d+)C', inFileData[inFileChar:])
|
||||
if m:
|
||||
for numRepeat in range(int(m[1])):
|
||||
outMap[inCurRow].append([curFg, curBg, self._CellState.CS_NONE, " "])
|
||||
inFileChar += len(m[0])
|
||||
elif inFileData[inFileChar:inFileChar+2] == "\r\n":
|
||||
inFileChar += 2; rowChars = width;
|
||||
elif inFileData[inFileChar] == "\r" \
|
||||
or inFileData[inFileChar] == "\n":
|
||||
inFileChar += 1; rowChars = width;
|
||||
else:
|
||||
outMap[inCurRow].append([curFg, curBg, self._CellState.CS_NONE, inFileData[inFileChar]])
|
||||
inFileChar += 1; rowChars += 1;
|
||||
if rowChars >= width:
|
||||
inMaxCols = max(inMaxCols, len(outMap[inCurRow])); inSize[1] += 1;
|
||||
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
|
||||
inCurColours = (15, 1)
|
||||
inCurCol += len(m[0])
|
||||
else:
|
||||
inCurColours = (15, 1); inCurCol += 1;
|
||||
elif inChar == "\u0006":
|
||||
inCellState = self._flipCellStateBit(self._CellState.CS_ITALIC, inCellState); inCurCol += 1;
|
||||
elif inChar == "\u000f":
|
||||
inCellState |= self._CellState.CS_NONE; inCurColours = (15, 1); inCurCol += 1;
|
||||
elif inChar == "\u0016":
|
||||
inCurColours = (inCurColours[1], inCurColours[0]); inCurCol += 1;
|
||||
elif inChar == "\u001f":
|
||||
inCellState = self._flipCellStateBit(self._CellState.CS_UNDERLINE, inCellState); inCurCol += 1;
|
||||
else:
|
||||
outMap[-1].append([*inCurColours, inCellState, inChar]); inCurCol += 1;
|
||||
inLine, outMaxCols = inFile.readline(), max(outMaxCols, len(outMap[-1]))
|
||||
if len(outMap[0]):
|
||||
self.inSize, self.outMap = [outMaxCols, len(outMap)], outMap
|
||||
return (True, None)
|
||||
else:
|
||||
return (False, "empty output map")
|
||||
# }}}
|
||||
# {{{ importTextFile(self, pathName): XXX
|
||||
def importTextFile(self, pathName):
|
||||
return self.importTextFileBuffer(open(pathName, "r", encoding="utf-8-sig"))
|
||||
# }}}
|
||||
# {{{ 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()
|
||||
with open(pathName, "r", encoding="utf-8-sig") as inFile:
|
||||
return self.importTextBuffer(inFile)
|
||||
# }}}
|
||||
|
||||
#
|
||||
# __init__(self, inFile=None, parentCanvas=None): initialisation method
|
||||
def __init__(self, inFile=None, parentCanvas=None):
|
||||
self.inSize, self.outMap, self.parentCanvas = None, None, parentCanvas
|
||||
# __init__(self, inFile=None): initialisation method
|
||||
def __init__(self, inFile=None):
|
||||
self.inSize, self.outMap = None, None
|
||||
if inFile != None:
|
||||
self.importTextFile(inFile)
|
||||
|
||||
|
@ -10,8 +10,7 @@ class CanvasJournal():
|
||||
# {{{ popCursor(self): XXX
|
||||
def popCursor(self):
|
||||
if len(self.patchesCursor):
|
||||
patchesCursor = self.patchesCursor
|
||||
self.patchesCursor = []
|
||||
patchesCursor = self.patchesCursor; self.patchesCursor = [];
|
||||
return patchesCursor
|
||||
else:
|
||||
return []
|
||||
@ -19,8 +18,7 @@ class CanvasJournal():
|
||||
# {{{ popRedo(self): XXX
|
||||
def popRedo(self):
|
||||
if self.patchesUndoLevel > 0:
|
||||
self.patchesUndoLevel -= 1
|
||||
patches = self.patchesUndo[self.patchesUndoLevel]
|
||||
self.patchesUndoLevel -= 1; patches = self.patchesUndo[self.patchesUndoLevel];
|
||||
return patches[1]
|
||||
else:
|
||||
return []
|
||||
@ -28,8 +26,7 @@ class CanvasJournal():
|
||||
# {{{ popUndo(self): XXX
|
||||
def popUndo(self):
|
||||
if self.patchesUndo[self.patchesUndoLevel] != None:
|
||||
patches = self.patchesUndo[self.patchesUndoLevel]
|
||||
self.patchesUndoLevel += 1
|
||||
patches = self.patchesUndo[self.patchesUndoLevel]; self.patchesUndoLevel += 1;
|
||||
return patches[0]
|
||||
else:
|
||||
return []
|
||||
@ -38,13 +35,11 @@ class CanvasJournal():
|
||||
def pushCursor(self, patches):
|
||||
self.patchesCursor.append(patches)
|
||||
# }}}
|
||||
# {{{ pushDeltas(self, undoPatches, redoPatches): XXX
|
||||
def pushDeltas(self, undoPatches, redoPatches):
|
||||
# {{{ pushDeltas(self, redoPatches, undoPatches): XXX
|
||||
def pushDeltas(self, redoPatches, undoPatches):
|
||||
if self.patchesUndoLevel > 0:
|
||||
del self.patchesUndo[0:self.patchesUndoLevel]
|
||||
self.patchesUndoLevel = 0
|
||||
deltaItem = [undoPatches, redoPatches]
|
||||
self.patchesUndo.insert(0, deltaItem)
|
||||
del self.patchesUndo[0:self.patchesUndoLevel]; self.patchesUndoLevel = 0;
|
||||
deltaItem = [undoPatches, redoPatches]; self.patchesUndo.insert(0, deltaItem);
|
||||
return deltaItem
|
||||
# }}}
|
||||
# {{{ resetCursor(self): XXX
|
||||
@ -59,10 +54,9 @@ class CanvasJournal():
|
||||
self.patchesUndo.clear()
|
||||
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)
|
||||
# {{{ updateCurrentDeltas(self, redoPatches, undoPatches): XXX
|
||||
def updateCurrentDeltas(self, redoPatches, undoPatches):
|
||||
self.patchesUndo[0][0].append(undoPatches); self.patchesUndo[0][1].append(redoPatches);
|
||||
# }}}
|
||||
|
||||
# {{{ __del__(self): destructor method
|
||||
|
@ -126,22 +126,22 @@ Colours = [
|
||||
# }}}
|
||||
# {{{ MiRCARTToAnsiColours: XXX
|
||||
MiRCARTToAnsiColours = [
|
||||
97, # Bright White
|
||||
30, # Black
|
||||
94, # Light Blue
|
||||
32, # Green
|
||||
91, # Red
|
||||
31, # Light Red
|
||||
35, # Pink
|
||||
33, # Yellow
|
||||
93, # Light Yellow
|
||||
92, # Light Green
|
||||
36, # Cyan
|
||||
96, # Light Cyan
|
||||
34, # Blue
|
||||
95, # Light Pink
|
||||
90, # Grey
|
||||
37, # Light Grey
|
||||
97, # Bright White
|
||||
30, # Black
|
||||
94, # Light Blue
|
||||
32, # Green
|
||||
91, # Red
|
||||
31, # Light Red
|
||||
35, # Pink
|
||||
33, # Yellow
|
||||
93, # Light Yellow
|
||||
92, # Light Green
|
||||
36, # Cyan
|
||||
96, # Light Cyan
|
||||
34, # Blue
|
||||
95, # Light Pink
|
||||
90, # Grey
|
||||
37, # Light Grey
|
||||
];
|
||||
# }}}
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
#
|
||||
|
||||
from ToolCircle import ToolCircle
|
||||
from ToolFill import ToolFill
|
||||
from ToolFill import ToolFill
|
||||
from ToolLine import ToolLine
|
||||
from ToolSelectClone import ToolSelectClone
|
||||
from ToolSelectMove import ToolSelectMove
|
||||
@ -19,13 +19,11 @@ import io, os, random, wx, wx.adv
|
||||
|
||||
class GuiCanvasInterface():
|
||||
"""XXX"""
|
||||
|
||||
# {{{ _dialogSaveChanges(self)
|
||||
# {{{ _dialogSaveChanges(self): XXX
|
||||
def _dialogSaveChanges(self):
|
||||
with wx.MessageDialog(self.parentCanvas, \
|
||||
"Do you want to save changes to {}?".format( \
|
||||
self.canvasPathName), "", \
|
||||
wx.CANCEL|wx.CANCEL_DEFAULT|wx.ICON_QUESTION|wx.YES_NO) as dialog:
|
||||
with wx.MessageDialog(self.parentCanvas, \
|
||||
"Do you want to save changes to {}?".format(self.canvasPathName), \
|
||||
"", wx.CANCEL|wx.CANCEL_DEFAULT|wx.ICON_QUESTION|wx.YES_NO) as dialog:
|
||||
dialogChoice = dialog.ShowModal()
|
||||
return dialogChoice
|
||||
# }}}
|
||||
@ -54,6 +52,105 @@ class GuiCanvasInterface():
|
||||
def canvasCut(self, event):
|
||||
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
|
||||
def canvasDecrBrushHeight(self, event):
|
||||
if self.parentCanvas.brushSize[1] > 1:
|
||||
@ -74,9 +171,7 @@ class GuiCanvasInterface():
|
||||
# {{{ canvasDecrCanvasHeight(self, event): XXX
|
||||
def canvasDecrCanvasHeight(self, event):
|
||||
if self.parentCanvas.canvasSize[1] > 1:
|
||||
self.parentCanvas.resize([ \
|
||||
self.parentCanvas.canvasSize[0], \
|
||||
self.parentCanvas.canvasSize[1]-1])
|
||||
self.parentCanvas.resize([self.parentCanvas.canvasSize[0], self.parentCanvas.canvasSize[1] - 1])
|
||||
# }}}
|
||||
# {{{ canvasDecrCanvasHeightWidth(self, event): XXX
|
||||
def canvasDecrCanvasHeightWidth(self, event):
|
||||
@ -86,36 +181,37 @@ class GuiCanvasInterface():
|
||||
# {{{ canvasDecrCanvasWidth(self, event): XXX
|
||||
def canvasDecrCanvasWidth(self, event):
|
||||
if self.parentCanvas.canvasSize[0] > 1:
|
||||
self.parentCanvas.resize([ \
|
||||
self.parentCanvas.canvasSize[0]-1, \
|
||||
self.parentCanvas.canvasSize[1]])
|
||||
self.parentCanvas.resize([self.parentCanvas.canvasSize[0] - 1, self.parentCanvas.canvasSize[1]])
|
||||
# }}}
|
||||
# {{{ canvasDelete(self, event): XXX
|
||||
def canvasDelete(self, event):
|
||||
pass
|
||||
# {{{ canvasIncrBrushHeight(self, event): XXX
|
||||
def canvasIncrBrushHeight(self, event):
|
||||
self.parentCanvas.brushSize[1] += 1
|
||||
self.parentFrame.onCanvasUpdate(brushSize=self.parentCanvas.brushSize)
|
||||
# }}}
|
||||
# {{{ 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)
|
||||
# {{{ canvasIncrBrushHeightWidth(self, event): XXX
|
||||
def canvasIncrBrushHeightWidth(self, event):
|
||||
self.canvasIncrBrushHeight(event)
|
||||
self.canvasIncrBrushWidth(event)
|
||||
# }}}
|
||||
# {{{ canvasExportToClipboard(self, event): XXX
|
||||
def canvasExportToClipboard(self, event):
|
||||
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
|
||||
outBuffer = self.parentCanvas.canvasExportStore.exportTextBuffer(self.parentCanvas.canvasMap, self.parentCanvas.canvasSize)
|
||||
if wx.TheClipboard.Open():
|
||||
wx.TheClipboard.SetData(wx.TextDataObject(outBuffer))
|
||||
wx.TheClipboard.Close()
|
||||
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
|
||||
return True
|
||||
# {{{ 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]])
|
||||
# }}}
|
||||
|
||||
# {{{ canvasExportAsAnsi(self, event): XXX
|
||||
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:
|
||||
@ -137,7 +233,7 @@ class GuiCanvasInterface():
|
||||
else:
|
||||
outPathName = dialog.GetPath()
|
||||
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.SetCursor(wx.Cursor(wx.NullCursor))
|
||||
return True
|
||||
@ -145,28 +241,23 @@ class GuiCanvasInterface():
|
||||
# {{{ canvasExportImgur(self, event): XXX
|
||||
def canvasExportImgur(self, event):
|
||||
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
|
||||
imgurResult = self.parentCanvas.canvasExportStore.exportBitmapToImgur( \
|
||||
self.imgurApiKey, self.parentCanvas.canvasBackend.canvasBitmap, \
|
||||
"", "", wx.BITMAP_TYPE_PNG)
|
||||
rc, status, result = self.parentCanvas.canvasExportStore.exportBitmapToImgur( \
|
||||
self.imgurApiKey, self.parentCanvas.canvasBackend.canvasBitmap, "", "", wx.BITMAP_TYPE_PNG)
|
||||
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
|
||||
if imgurResult[0] == 200:
|
||||
if rc:
|
||||
if not wx.TheClipboard.IsOpened():
|
||||
wx.TheClipboard.Open()
|
||||
wx.TheClipboard.SetData(wx.TextDataObject(imgurResult[1]))
|
||||
wx.TheClipboard.Close()
|
||||
wx.MessageBox("Exported to Imgur: " + imgurResult[1], \
|
||||
"Export to Imgur", wx.OK|wx.ICON_INFORMATION)
|
||||
wx.TheClipboard.Open(); wx.TheClipboard.SetData(wx.TextDataObject(result)); wx.TheClipboard.Close();
|
||||
wx.MessageBox("Exported to Imgur: {}".format(result), "Export to Imgur", wx.ICON_INFORMATION | wx.OK)
|
||||
else:
|
||||
wx.MessageBox("Failed to export to Imgur: " + imgurResult[1], \
|
||||
"Export to Imgur", wx.OK|wx.ICON_EXCLAMATION)
|
||||
wx.MessageBox("Failed to export to Imgur: {}".format(result), "Export to Imgur", wx.ICON_EXCLAMATION | wx.OK)
|
||||
# }}}
|
||||
# {{{ canvasExportPastebin(self, event): XXX
|
||||
def canvasExportPastebin(self, event):
|
||||
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
|
||||
pasteStatus, pasteResult = \
|
||||
self.parentCanvas.canvasExportStore.exportPastebin( \
|
||||
"", \
|
||||
self.parentCanvas.canvasMap, \
|
||||
pasteStatus, pasteResult = \
|
||||
self.parentCanvas.canvasExportStore.exportPastebin( \
|
||||
"", \
|
||||
self.parentCanvas.canvasMap, \
|
||||
self.parentCanvas.canvasSize)
|
||||
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
|
||||
if pasteStatus:
|
||||
@ -174,11 +265,19 @@ class GuiCanvasInterface():
|
||||
wx.TheClipboard.Open()
|
||||
wx.TheClipboard.SetData(wx.TextDataObject(pasteResult))
|
||||
wx.TheClipboard.Close()
|
||||
wx.MessageBox("Exported to Pastebin: " + pasteResult, \
|
||||
"Export to Pastebin", wx.OK|wx.ICON_INFORMATION)
|
||||
wx.MessageBox("Exported to Pastebin: " + pasteResult, "Export to Pastebin", wx.OK|wx.ICON_INFORMATION)
|
||||
else:
|
||||
wx.MessageBox("Failed to export to Pastebin: " + pasteResult, \
|
||||
"Export to Pastebin", wx.OK|wx.ICON_EXCLAMATION)
|
||||
wx.MessageBox("Failed to export to Pastebin: " + pasteResult, "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
|
||||
def canvasImportAnsi(self, event):
|
||||
@ -196,17 +295,21 @@ class GuiCanvasInterface():
|
||||
else:
|
||||
self.canvasPathName = dialog.GetPath()
|
||||
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
|
||||
self.parentCanvas.canvasImportStore.importAnsiFile(self.canvasPathName)
|
||||
self.parentCanvas.canvasImportStore.importIntoPanel()
|
||||
self.canvasPathName = "(Imported)"
|
||||
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
|
||||
self.parentFrame.onCanvasUpdate(pathName="(Imported)", undoLevel=-1)
|
||||
return True
|
||||
rc, error = self.parentCanvas.canvasImportStore.importAnsiFile(self.canvasPathName)
|
||||
if rc:
|
||||
self.parentCanvas.onStoreUpdate(self.parentCanvas.canvasImportStore.inSize, self.parentCanvas.canvasImportStore.outMap)
|
||||
self.canvasPathName = "(Imported)"
|
||||
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
|
||||
self.parentFrame.onCanvasUpdate(pathName="(Imported)", undoLevel=-1)
|
||||
return True
|
||||
else:
|
||||
print("error: {}".format(error), file=sys.stderr)
|
||||
return False
|
||||
# }}}
|
||||
# {{{ canvasImportFromClipboard(self, event): XXX
|
||||
def canvasImportFromClipboard(self, event):
|
||||
rc = False
|
||||
if wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_TEXT)) \
|
||||
if wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_TEXT)) \
|
||||
and wx.TheClipboard.Open():
|
||||
inBuffer = wx.TextDataObject()
|
||||
if wx.TheClipboard.GetData(inBuffer):
|
||||
@ -219,12 +322,14 @@ class GuiCanvasInterface():
|
||||
elif saveChanges == wx.ID_YES:
|
||||
self.canvasSave(event)
|
||||
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
|
||||
self.parentCanvas.canvasImportStore.importTextFileBuffer(io.StringIO(inBuffer.GetText()))
|
||||
self.parentCanvas.canvasImportStore.importIntoPanel()
|
||||
self.canvasPathName = "(Clipboard)"
|
||||
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
|
||||
self.parentFrame.onCanvasUpdate(pathName="(Clipboard)", undoLevel=-1)
|
||||
rc = True
|
||||
rc, error = self.parentCanvas.canvasImportStore.importTextBuffer(io.StringIO(inBuffer.GetText()))
|
||||
if rc:
|
||||
self.parentCanvas.onStoreUpdate(self.parentCanvas.canvasImportStore.inSize, self.parentCanvas.canvasImportStore.outMap)
|
||||
self.canvasPathName = "(Clipboard)"
|
||||
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
|
||||
self.parentFrame.onCanvasUpdate(pathName="(Clipboard)", undoLevel=-1)
|
||||
else:
|
||||
print("error: {}".format(error), file=sys.stderr)
|
||||
wx.TheClipboard.Close()
|
||||
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:
|
||||
@ -246,121 +351,18 @@ class GuiCanvasInterface():
|
||||
else:
|
||||
self.canvasPathName = dialog.GetPath()
|
||||
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
|
||||
self.parentCanvas.canvasImportStore.importSauceFile(self.canvasPathName)
|
||||
self.parentCanvas.canvasImportStore.importIntoPanel()
|
||||
self.canvasPathName = "(Imported)"
|
||||
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
|
||||
self.parentFrame.onCanvasUpdate(pathName="(Imported)", undoLevel=-1)
|
||||
return True
|
||||
# }}}
|
||||
# {{{ canvasIncrBrushHeight(self, event): XXX
|
||||
def canvasIncrBrushHeight(self, event):
|
||||
self.parentCanvas.brushSize[1] += 1
|
||||
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)
|
||||
rc, error = self.parentCanvas.canvasImportStore.importSauceFile(self.canvasPathName)
|
||||
if rc:
|
||||
self.parentCanvas.onStoreUpdate(self.parentCanvas.canvasImportStore.inSize, self.parentCanvas.canvasImportStore.outMap)
|
||||
self.canvasPathName = "(Imported)"
|
||||
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
|
||||
self.parentFrame.onCanvasUpdate(pathName="(Imported)", undoLevel=-1)
|
||||
return True
|
||||
else:
|
||||
print("error: {}".format(error), file=sys.stderr)
|
||||
return False
|
||||
# }}}
|
||||
|
||||
# {{{ canvasToolCircle(self, event): XXX
|
||||
def canvasToolCircle(self, event):
|
||||
self.canvasTool = ToolCircle(self.parentCanvas)
|
||||
@ -417,11 +419,6 @@ class GuiCanvasInterface():
|
||||
toolBar.ToggleTool(self.parentFrame.CID_TEXT[0], True)
|
||||
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):
|
||||
|
@ -180,7 +180,7 @@ class GuiFrame(GuiGeneralFrame):
|
||||
textItems.append("Current tool: {}".format( \
|
||||
self.lastPanelState["toolName"]))
|
||||
self.statusBar.SetStatusText(" | ".join(textItems))
|
||||
if "undoLevel" in self.lastPanelState:
|
||||
if "undoLevel" in self.lastPanelState:
|
||||
if self.lastPanelState["undoLevel"] >= 0:
|
||||
self.menuItemsById[self.CID_UNDO[0]].Enable(True)
|
||||
toolBar = self.toolBarItemsById[self.CID_UNDO[0]].GetToolBar()
|
||||
|
@ -28,7 +28,7 @@ class ToolRect(Tool):
|
||||
patch = [atPoint[0] + brushCol, atPoint[1] + brushRow, *brushColours, 0, " "]
|
||||
if isLeftDown or isRightDown:
|
||||
dispatchFn(eventDc, False, patch); dispatchFn(eventDc, True, patch);
|
||||
else:
|
||||
else:
|
||||
dispatchFn(eventDc, True, patch)
|
||||
|
||||
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
||||
|
9
roar.py
9
roar.py
@ -19,9 +19,12 @@ def main(*argv):
|
||||
if len(argv) > 1 \
|
||||
and len(argv[1]) > 0:
|
||||
appFrame.panelCanvas.canvasInterface.canvasPathName = argv[1]
|
||||
appFrame.panelCanvas.canvasImportStore.importTextFile(argv[1])
|
||||
appFrame.panelCanvas.canvasImportStore.importIntoPanel()
|
||||
appFrame.onCanvasUpdate(pathName=argv[1], undoLevel=-1)
|
||||
rc, error = appFrame.panelCanvas.canvasImportStore.importTextFile(argv[1])
|
||||
if rc:
|
||||
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()
|
||||
if __name__ == "__main__":
|
||||
main(*sys.argv)
|
||||
|
Loading…
Reference in New Issue
Block a user