libcanvas/CanvasColours.py, libgui/GuiCanvasColours.py: split from libcanvas/CanvasColours.py.

libcanvas/Canvas.py, libgui/GuiCanvasPanel.py: split from libcanvas/Canvas.py.
libcanvas/CanvasImportStore.py:import{Ansi{Buffer,File},SauceFile}(): fixed (via spoke.)
{libgui/Gui{CanvasInterface,Frame},libtools/Tool{Fill,Select,Text},roar}.py: updated.
libgui/GuiCanvasWxBackend.py: merged from libcanvas/CanvasBackend.py.
This commit is contained in:
Lucio Andrés Illanes Albornoz 2019-09-07 10:39:26 +02:00
parent c28c2f87ab
commit f3140d4b3d
13 changed files with 361 additions and 339 deletions

View File

@ -1,14 +1,15 @@
1) General {cleanup,refactor} 1) General {cleanup,refactor}
2) Implement ANSI CSI CU[BDPU] sequences 2) Transparent {back,fore}ground colour
3) Incremental auto{load,save} & {backup,restore} 3) Implement ANSI CSI CU[BDPU] sequences
4) Open and toggle a reference image in the background 4) Incremental auto{load,save} & {backup,restore}
5) Client-Server or Peer-to-Peer realtime collaboration 5) Open and toggle a reference image in the background
6) Arbitrary {format,palette}s ({4,8} bit ANSI/mIRC, etc.) 6) Client-Server or Peer-to-Peer realtime collaboration
7) Hotkey & graphical interfaces to {composed,parametrised} tools 7) Arbitrary {format,palette}s ({4,8} bit ANSI/mIRC, etc.)
8) GUI: a) scrollbar b) switch from wxPython to GTK c) revisit About dialogue 8) Hotkey & graphical interfaces to {composed,parametrised} tools
9) Layers, layout (e.g. for comics, zines, etc.) & asset management (e.g. kade, lion, etc.) & traits w/ {inserting,merging,linking} 9) GUI: a) scrollbar b) switch from wxPython to GTK c) revisit About dialogue
10) Sprites & scripted (Python?) animation on the basis of asset traits and {composable,parametrised} patterns (metric flow, particle system, rigging, ...) 10) Layers, layout (e.g. for comics, zines, etc.) & asset management (e.g. kade, lion, etc.) & traits w/ {inserting,merging,linking}
11) Composition and parametrisation of tools from higher-order operators (brushes, filters, outlines, patterns & shaders) and unit tools; unit tools: 11) Sprites & scripted (Python?) animation on the basis of asset traits and {composable,parametrised} patterns (metric flow, particle system, rigging, ...)
13) Composition and parametrisation of tools from higher-order operators (brushes, filters, outlines, patterns & shaders) and unit tools; unit tools:
a) geometric primitives (arrow, circle, cloud/speech bubble, curve, heart, hexagon, line, pentagon, polygon, rhombus, triangle, square, star) a) geometric primitives (arrow, circle, cloud/speech bubble, curve, heart, hexagon, line, pentagon, polygon, rhombus, triangle, square, star)
b) regions (crop, duplicate, erase, fill, invert, measure, pick, rotate, scale, select, shift, slice, tile, translate) b) regions (crop, duplicate, erase, fill, invert, measure, pick, rotate, scale, select, shift, slice, tile, translate)
c) text (edit, Unicode sets) c) text (edit, Unicode sets)

View File

@ -4,194 +4,90 @@
# Copyright (c) 2018, 2019 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de> # Copyright (c) 2018, 2019 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
# #
from CanvasBackend import CanvasBackend from CanvasExportStore import CanvasExportStore
from CanvasJournal import CanvasJournal
from CanvasExportStore import CanvasExportStore, havePIL, haveUrllib
from CanvasImportStore import CanvasImportStore from CanvasImportStore import CanvasImportStore
import wx from CanvasJournal import CanvasJournal
class Canvas(wx.Panel): class Canvas():
"""XXX""" """XXX"""
# {{{ _commitPatch(self, patch): XXX # {{{ _commitPatch(self, patch): XXX
def _commitPatch(self, patch): def _commitPatch(self, patch):
self.canvasMap[patch[1]][patch[0]] = patch[2:] self.map[patch[1]][patch[0]] = patch[2:]
# }}}
# {{{ _dispatchDeltaPatches(self, deltaPatches): XXX
def _dispatchDeltaPatches(self, deltaPatches):
eventDc = self.canvasBackend.getDeviceContext(self)
for patch in deltaPatches:
if patch[0] == "resize":
del eventDc
self.resize(patch[1:], False)
eventDc = self.canvasBackend.getDeviceContext(self)
elif self.canvasBackend.drawPatch(eventDc, patch):
self._commitPatch(patch)
self.parentFrame.onCanvasUpdate(undoLevel=self.canvasJournal.patchesUndoLevel)
# }}}
# {{{ _dispatchPatch(self, eventDc, isCursor, patch, commitUndo=True): XXX
def _dispatchPatch(self, eventDc, isCursor, patch, commitUndo=True):
if not self._canvasDirtyCursor:
self.canvasBackend.drawCursorMaskWithJournal(self.canvasJournal, eventDc)
self._canvasDirtyCursor = True
if self.canvasBackend.drawPatch(eventDc, patch):
patchDeltaCell = self.canvasMap[patch[1]][patch[0]]
patchDelta = [*patch[0:2], *patchDeltaCell]
if isCursor and commitUndo:
self.canvasJournal.pushCursor(patchDelta)
else:
if commitUndo:
if not self._canvasDirty:
self.canvasJournal.pushDeltas([], []); self._canvasDirty = True;
self.canvasJournal.updateCurrentDeltas(patch, patchDelta)
self._commitPatch(patch)
# }}} # }}}
# {{{ onPanelClose(self, event): XXX # {{{ dispatchPatch(self, isCursor, patch, commitUndo=True): XXX
def onPanelClose(self, event): def dispatchPatch(self, isCursor, patch, commitUndo=True):
self.Destroy() patchDeltaCell = self.map[patch[1]][patch[0]]; patchDelta = [*patch[0:2], *patchDeltaCell];
# }}} if isCursor:
# {{{ onPanelEnterWindow(self, event): XXX self.journal.pushCursor(patchDelta)
def onPanelEnterWindow(self, event):
self.parentFrame.SetFocus()
# }}}
# {{{ onPanelInput(self, event): XXX
def onPanelInput(self, event):
eventDc = self.canvasBackend.getDeviceContext(self)
eventType = event.GetEventType()
self._canvasDirty = self._canvasDirtyCursor = False
tool = self.canvasInterface.canvasTool
if eventType == wx.wxEVT_CHAR:
mapPoint = self.brushPos
doSkip = tool.onKeyboardEvent( \
event, mapPoint, self.brushColours, self.brushSize, \
chr(event.GetUnicodeKey()), self._dispatchPatch, eventDc)
if doSkip:
event.Skip(); return;
else: else:
mapPoint = self.canvasBackend.xlateEventPoint(event, eventDc)
if mapPoint[0] >= self.canvasSize[0] \
or mapPoint[1] >= self.canvasSize[1]:
return
self.brushPos = mapPoint
tool.onMouseEvent( \
event, mapPoint, self.brushColours, self.brushSize, \
event.Dragging(), event.LeftIsDown(), event.RightIsDown(), \
self._dispatchPatch, eventDc)
if self._canvasDirty:
self.parentFrame.onCanvasUpdate(cellPos=self.brushPos, undoLevel=self.canvasJournal.patchesUndoLevel)
if eventType == wx.wxEVT_MOTION:
self.parentFrame.onCanvasUpdate(cellPos=mapPoint)
# }}}
# {{{ onPanelLeaveWindow(self, event): XXX
def onPanelLeaveWindow(self, event):
eventDc = self.canvasBackend.getDeviceContext(self)
self.canvasBackend.drawCursorMaskWithJournal(self.canvasJournal, eventDc)
# }}}
# {{{ onPanelPaint(self, event): XXX
def onPanelPaint(self, event):
self.canvasBackend.onPanelPaintEvent(event, self)
# }}}
# {{{ onStoreUpdate(self, newCanvasSize, newCanvas=None): XXX
def onStoreUpdate(self, newCanvasSize, newCanvas=None):
self.resize(newCanvasSize=newCanvasSize, commitUndo=False)
eventDc = self.canvasBackend.getDeviceContext(self)
for numRow in range(self.canvasSize[1]):
for numCol in range(self.canvasSize[0]):
if newCanvas != None \
and numRow < len(newCanvas) \
and numCol < len(newCanvas[numRow]):
self._commitPatch([numCol, numRow, *newCanvas[numRow][numCol]])
self.canvasBackend.drawPatch(eventDc, [numCol, numRow, *self.canvasMap[numRow][numCol]])
wx.SafeYield()
# }}}
# {{{ resize(self, newCanvasSize, commitUndo=True): XXX
def resize(self, newCanvasSize, commitUndo=True):
if newCanvasSize != self.canvasSize:
self._canvasDirty, self._canvasDirtyCursor = False, False
if self.canvasMap == None:
self.canvasMap, oldCanvasSize = [], [0, 0]
else:
oldCanvasSize = self.canvasSize
deltaCanvasSize = [b - a for a, b in zip(oldCanvasSize, newCanvasSize)]
newWinSize = [a * b for a, b in zip(newCanvasSize, self.canvasBackend.cellSize)]
self.SetMinSize(newWinSize); self.SetSize(wx.DefaultCoord, wx.DefaultCoord, *newWinSize);
curWindow = self
while curWindow != None:
curWindow.Layout(); curWindow = curWindow.GetParent();
self.canvasBackend.resize(newCanvasSize, self.canvasBackend.cellSize)
eventDc = self.canvasBackend.getDeviceContext(self)
self.canvasJournal.resetCursor()
if commitUndo: if commitUndo:
undoPatches, redoPatches = ["resize", *oldCanvasSize], ["resize", *newCanvasSize] if not self.dirty:
if not self._canvasDirty: self.journal.pushDeltas([], []); self.dirty = True;
self.canvasJournal.pushDeltas([], []); self._canvasDirty = True; self.journal.updateCurrentDeltas(patch, patchDelta)
self.canvasJournal.updateCurrentDeltas(redoPatches, undoPatches) self._commitPatch(patch)
if deltaCanvasSize[0] < 0:
for numRow in range(oldCanvasSize[1]):
if commitUndo:
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, 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]):
self.canvasMap[numRow].extend([[1, 1, 0, " "]] * deltaCanvasSize[0])
for numNewCol in range(oldCanvasSize[0], newCanvasSize[0]):
self._dispatchPatch(eventDc, False, [numNewCol, numRow, 1, 1, 0, " "], commitUndo)
if deltaCanvasSize[1] < 0:
if commitUndo:
for numRow in range((oldCanvasSize[1] + deltaCanvasSize[1]), oldCanvasSize[1]):
for numCol in range(oldCanvasSize[0] + deltaCanvasSize[0]):
if not self._canvasDirty:
self.canvasJournal.pushDeltas([], []); self._canvasDirty = True;
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]):
self.canvasMap.extend([[[1, 1, 0, " "]] * newCanvasSize[0]])
for numNewCol in range(newCanvasSize[0]):
self._dispatchPatch(eventDc, False, [numNewCol, numNewRow, 1, 1, 0, " "], commitUndo)
self.canvasSize = newCanvasSize; wx.SafeYield(); self.parentFrame.onCanvasUpdate(size=newCanvasSize, undoLevel=self.canvasJournal.patchesUndoLevel)
# }}} # }}}
# {{{ resize(self, newSize, commitUndo=True): XXX
# {{{ __del__(self): destructor method def resize(self, newSize, commitUndo=True):
def __del__(self): if newSize != self.size:
if self.canvasMap != None: self.dirty = False
self.canvasMap.clear(); self.canvasMap = None; if self.map == None:
self.map, oldSize = [], [0, 0]
else:
oldSize = self.size
deltaSize = [b - a for a, b in zip(oldSize, newSize)]
self.journal.resetCursor()
if commitUndo:
undoPatches, redoPatches = ["resize", *oldSize], ["resize", *newSize]
if not self.dirty:
self.journal.pushDeltas([], []); self.dirty = True;
self.journal.updateCurrentDeltas(redoPatches, undoPatches)
if deltaSize[0] < 0:
for numRow in range(oldSize[1]):
if commitUndo:
for numCol in range((oldSize[0] + deltaSize[0]), oldSize[0]):
if not self.dirty:
self.journal.pushDeltas([], []); self.dirty = True;
self.journal.updateCurrentDeltas(None, [numCol, numRow, *self.map[numRow][numCol]])
del self.map[numRow][-1:(deltaSize[0]-1):-1]
else:
for numRow in range(oldSize[1]):
self.map[numRow].extend([[1, 1, 0, " "]] * deltaSize[0])
for numNewCol in range(oldSize[0], newSize[0]):
self.dispatchPatch(False, [numNewCol, numRow, 1, 1, 0, " "], commitUndo)
if deltaSize[1] < 0:
if commitUndo:
for numRow in range((oldSize[1] + deltaSize[1]), oldSize[1]):
for numCol in range(oldSize[0] + deltaSize[0]):
if not self.dirty:
self.journal.pushDeltas([], []); self.dirty = True;
self.journal.updateCurrentDeltas(None, [numCol, numRow, *self.map[numRow][numCol]])
del self.map[-1:(deltaSize[1]-1):-1]
else:
for numNewRow in range(oldSize[1], newSize[1]):
self.map.extend([[[1, 1, 0, " "]] * newSize[0]])
for numNewCol in range(newSize[0]):
self.dispatchPatch(False, [numNewCol, numNewRow, 1, 1, 0, " "], commitUndo)
self.size = newSize
return True
else:
return False
# }}}
# {{{ update(self, newSize, newCanvas=None): XXX
def update(self, newSize, newCanvas=None):
for numRow in range(self.size[1]):
for numCol in range(self.size[0]):
if (newCanvas != None) \
and (numRow < len(newCanvas)) \
and (numCol < len(newCanvas[numRow])):
self._commitPatch([numCol, numRow, *newCanvas[numRow][numCol]])
# }}} # }}}
# #
# __init__(self, parent, parentFrame, canvasInterface, defaultCanvasPos, defaultCanvasSize, defaultCellSize): initialisation method # __init__(self, size): initialisation method
def __init__(self, parent, parentFrame, canvasInterface, defaultCanvasPos, defaultCanvasSize, defaultCellSize): def __init__(self, size):
super().__init__(parent, pos=defaultCanvasPos, size=[w * h for w, h in zip(defaultCanvasSize, defaultCellSize)]) self.dirty, self.dirtyCursor, self.map, self.size = False, False, None, size
self.exportStore, self.importStore, self.journal = CanvasExportStore(), CanvasImportStore(), CanvasJournal()
self.brushColours, self.brushPos, self.brushSize = [4, 1], [0, 0], [1, 1]
self._canvasDirty, self._canvasDirtyCursor = False, False
self.canvasMap, self.canvasPos, self.canvasSize, = None, defaultCanvasPos, defaultCanvasSize
self.defaultCanvasPos, self.defaultCanvasSize, self.defaultCellSize = defaultCanvasPos, defaultCanvasSize, defaultCellSize
self.parentFrame = parentFrame
self.parentFrame.onCanvasUpdate(brushSize=self.brushSize, colours=self.brushColours)
self.canvasBackend = CanvasBackend(defaultCanvasSize, defaultCellSize)
self.canvasJournal = CanvasJournal()
self.canvasExportStore = CanvasExportStore()
self.canvasImportStore = CanvasImportStore()
self.canvasInterface = canvasInterface(self, parentFrame)
# Bind event handlers
self.Bind(wx.EVT_CLOSE, self.onPanelClose)
self.Bind(wx.EVT_ENTER_WINDOW, self.onPanelEnterWindow)
self.Bind(wx.EVT_LEAVE_WINDOW, self.onPanelLeaveWindow)
self.parentFrame.Bind(wx.EVT_CHAR, self.onPanelInput)
for eventType in (wx.EVT_LEFT_DOWN, wx.EVT_MOTION, wx.EVT_RIGHT_DOWN):
self.Bind(eventType, self.onPanelInput)
self.Bind(wx.EVT_PAINT, self.onPanelPaint)
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=0 # vim:expandtab foldmethod=marker sw=4 ts=4 tw=0

View File

@ -104,26 +104,6 @@ ColourMapNormal = [
[187, 187, 187], # Light Grey [187, 187, 187], # Light Grey
] ]
# }}} # }}}
# {{{ Colours: mIRC colour number to RGBA map given none of ^[BFV_] (bold, italic, reverse, underline],
Colours = [
[255, 255, 255, 255, "White"],
[0, 0, 0, 255, "Black"],
[0, 0, 187, 255, "Blue"],
[0, 187, 0, 255, "Green"],
[255, 85, 85, 255, "Light Red"],
[187, 0, 0, 255, "Red"],
[187, 0, 187, 255, "Purple"],
[187, 187, 0, 255, "Yellow"],
[255, 255, 85, 255, "Light Yellow"],
[85, 255, 85, 255, "Light Green"],
[0, 187, 187, 255, "Cyan"],
[85, 255, 255, 255, "Light Cyan"],
[85, 85, 255, 255, "Light Blue"],
[255, 85, 255, 255, "Pink"],
[85, 85, 85, 255, "Grey"],
[187, 187, 187, 255, "Light Grey"],
];
# }}}
# {{{ MiRCARTToAnsiColours: XXX # {{{ MiRCARTToAnsiColours: XXX
MiRCARTToAnsiColours = [ MiRCARTToAnsiColours = [
97, # Bright White 97, # Bright White

View File

@ -6,7 +6,7 @@
# #
from CanvasColours import AnsiBgToMiRCARTColours, AnsiFgToMiRCARTColours, AnsiFgBoldToMiRCARTColours from CanvasColours import AnsiBgToMiRCARTColours, AnsiFgToMiRCARTColours, AnsiFgBoldToMiRCARTColours
import os, re, struct, sys import io, os, re, struct, sys
class CanvasImportStore(): class CanvasImportStore():
"""XXX""" """XXX"""
@ -23,17 +23,17 @@ class CanvasImportStore():
return cellState & ~bit if cellState & bit else cellState | bit return cellState & ~bit if cellState & bit else cellState | bit
# }}} # }}}
# {{{ importAnsiBuffer(self, inFile, encoding="cp437", width=None): XXX # {{{ importAnsiBuffer(self, inBuffer, encoding="cp437", width=None): XXX
def importAnsiBuffer(self, inFile, encoding="cp437", width=None): def importAnsiBuffer(self, inBuffer, encoding="cp437", width=None):
curBg, curBgAnsi, curBoldAnsi, curFg, curFgAnsi = 1, 30, False, 15, 37 curBg, curBgAnsi, curBoldAnsi, curFg, curFgAnsi = 1, 30, False, 15, 37
done, outMap, outMaxCols = False, [[]], 0 done, outMap, outMaxCols = False, [[]], 0
inFileData = inFile.read().decode(encoding) inBufferData = inBuffer.decode(encoding)
inFileChar, inFileCharMax = 0, len(inFileData) inBufferChar, inBufferCharMax = 0, len(inBufferData)
while True: while True:
if inFileChar >= inFileCharMax: if inBufferChar >= inBufferCharMax:
break break
else: else:
m = re.match("\x1b\[((?:\d{1,3};?)+m|\d+C)", inFileData[inFileChar:]) m = re.match("\x1b\[((?:\d{1,3};?)+m|\d+[ABCDEFG])", inBufferData[inBufferChar:])
if m: if m:
if m[1][-1] == "C": if m[1][-1] == "C":
outMap[-1] += [[curFg, curBg, self._CellState.CS_NONE, " "]] * int(m[1][:-1]) outMap[-1] += [[curFg, curBg, self._CellState.CS_NONE, " "]] * int(m[1][:-1])
@ -48,25 +48,26 @@ class CanvasImportStore():
curBoldAnsi, newFg = False, AnsiFgToMiRCARTColours[curFgAnsi] curBoldAnsi, newFg = False, AnsiFgToMiRCARTColours[curFgAnsi]
elif ansiCode == 7: elif ansiCode == 7:
curBgAnsi, curFgAnsi, newBg, newFg = curFgAnsi, curBgAnsi, curFg, curBg curBgAnsi, curFgAnsi, newBg, newFg = curFgAnsi, curBgAnsi, curFg, curBg
elif ansiCode in AnsiBgToMiRCARTColours: elif (not curBoldAnsi) and (ansiCode in AnsiBgToMiRCARTColours):
curBgAnsi, newBg = ansiCode, AnsiBgToMiRCARTColours[ansiCode] curBgAnsi, newBg = ansiCode, AnsiBgToMiRCARTColours[ansiCode]
elif ansiCode in AnsiFgBoldToMiRCARTColours: elif curBoldAnsi and (ansiCode in AnsiFgBoldToMiRCARTColours):
curFgAnsi, newFg = ansiCode, AnsiFgBoldToMiRCARTColours[ansiCode] curFgAnsi, newFg = ansiCode, AnsiFgBoldToMiRCARTColours[ansiCode]
elif ansiCode in AnsiFgToMiRCARTColours: elif ansiCode in AnsiFgToMiRCARTColours:
newFg = AnsiFgBoldToMiRCARTColours[ansiCode] if curBoldAnsi else AnsiFgToMiRCARTColours[ansiCode] newFg = AnsiFgBoldToMiRCARTColours[ansiCode] if curBoldAnsi else AnsiFgToMiRCARTColours[ansiCode]
curFgAnsi = ansiCode curFgAnsi = ansiCode
curBg = newBg if newBg != -1 else curBg; curFg = newFg if newFg != -1 else curFg; curBg = newBg if newBg != -1 else curBg; curFg = newFg if newFg != -1 else curFg;
inFileChar += len(m[0]) inBufferChar += len(m[0])
elif inFileData[inFileChar:inFileChar + 2] == "\r\n": elif inBufferData[inBufferChar:inBufferChar + 2] == "\r\n":
done = True; inFileChar += 2; done = True; inBufferChar += 2;
elif inFileData[inFileChar] in set("\r\n"): elif inBufferData[inBufferChar] in set("\r\n"):
done = True; inFileChar += 1; done = True; inBufferChar += 1;
else: else:
outMap[-1].append([curFg, curBg, self._CellState.CS_NONE, inFileData[inFileChar]]) outMap[-1].append([curFg, curBg, self._CellState.CS_NONE, inBufferData[inBufferChar]])
inFileChar += 1 inBufferChar += 1
if done or (width == len(outMap[-1])): if done or (width == len(outMap[-1])):
done, outMaxCols, = False, max(outMaxCols, len(outMap[-1])); outMap.append([]); done, outMaxCols, = False, max(outMaxCols, len(outMap[-1])); outMap.append([]);
if len(outMap[0]): if (len(outMap) > 1) \
or ((len(outMap) == 1) and len(outMap[0])):
for numRow in range(len(outMap)): for numRow in range(len(outMap)):
for numCol in range(len(outMap[numRow]), outMaxCols): for numCol in range(len(outMap[numRow]), outMaxCols):
outMap[numRow].append([curFg, curBg, self._CellState.CS_NONE, " "]) outMap[numRow].append([curFg, curBg, self._CellState.CS_NONE, " "])
@ -77,16 +78,17 @@ class CanvasImportStore():
# }}} # }}}
# {{{ importAnsiFile(self, inPathName, encoding="cp437"): XXX # {{{ importAnsiFile(self, inPathName, encoding="cp437"): XXX
def importAnsiFile(self, inPathName, encoding="cp437"): def importAnsiFile(self, inPathName, encoding="cp437"):
return self.importAnsiBuffer(open(inPathName, "rb"), encoding) return self.importAnsiBuffer(open(inPathName, "rb").read(), encoding)
# }}} # }}}
# {{{ importSauceFile(self, inPathName): XXX # {{{ importSauceFile(self, inPathName, encoding="cp437"): XXX
def importSauceFile(self, inPathName): def importSauceFile(self, inPathName, encoding="cp437"):
with open(inPathName, "rb") as inFile: with open(inPathName, "rb") as inFile:
inFileStat = os.stat(inPathName); inFile.seek(inFileStat.st_size - 128, 0); inFile.seek(94); inFileStat = os.stat(inPathName)
inFile.seek(inFileStat.st_size - 128, os.SEEK_SET); inFile.seek(94, os.SEEK_CUR);
if inFile.read(2) == b'\x01\x01': if inFile.read(2) == b'\x01\x01':
width = struct.unpack("H", inFile.read(2))[0] width = struct.unpack("H", inFile.read(2))[0]
inFile.seek(0, 0); inFileData = inFile.read(inFileStat.st_size - 128); inFile.seek(0, 0); inFileData = inFile.read(inFileStat.st_size - 128);
return self.importAnsiFileBuffer(io.StringIO(inFileData), width) return self.importAnsiBuffer(inFileData, encoding, width)
else: else:
return (False, "only character based ANSi SAUCE files are supported") return (False, "only character based ANSi SAUCE files are supported")
# }}} # }}}
@ -124,7 +126,8 @@ class CanvasImportStore():
else: else:
outMap[-1].append([*inCurColours, inCellState, inChar]); inCurCol += 1; outMap[-1].append([*inCurColours, inCellState, inChar]); inCurCol += 1;
inLine, outMaxCols = inFile.readline(), max(outMaxCols, len(outMap[-1])) inLine, outMaxCols = inFile.readline(), max(outMaxCols, len(outMap[-1]))
if len(outMap[0]): if (len(outMap) > 1) \
or ((len(outMap) == 1) and len(outMap[0])):
self.inSize, self.outMap = [outMaxCols, len(outMap)], outMap self.inSize, self.outMap = [outMaxCols, len(outMap)], outMap
return (True, None) return (True, None)
else: else:

View File

@ -0,0 +1,29 @@
#!/usr/bin/env python3
#
# GuiCanvasColours.py -- XXX
# Copyright (c) 2018, 2019 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
#
#
# Colours: mIRC colour number to RGBA map given none of ^[BFV_] (bold, italic, reverse, underline)
#
Colours = [
[255, 255, 255, 255, "White"],
[0, 0, 0, 255, "Black"],
[0, 0, 187, 255, "Blue"],
[0, 187, 0, 255, "Green"],
[255, 85, 85, 255, "Light Red"],
[187, 0, 0, 255, "Red"],
[187, 0, 187, 255, "Purple"],
[187, 187, 0, 255, "Yellow"],
[255, 255, 85, 255, "Light Yellow"],
[85, 255, 85, 255, "Light Green"],
[0, 187, 187, 255, "Cyan"],
[85, 255, 255, 255, "Light Cyan"],
[85, 85, 255, 255, "Light Blue"],
[255, 85, 255, 255, "Pink"],
[85, 85, 85, 255, "Grey"],
[187, 187, 187, 255, "Light Grey"],
];
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -15,7 +15,7 @@ from ToolText import ToolText
from glob import glob from glob import glob
from GuiCanvasInterfaceAbout import GuiCanvasInterfaceAbout from GuiCanvasInterfaceAbout import GuiCanvasInterfaceAbout
from ImgurApiKey import ImgurApiKey from ImgurApiKey import ImgurApiKey
import io, os, random, wx, wx.adv import io, os, random, sys, wx, wx.adv
class GuiCanvasInterface(): class GuiCanvasInterface():
"""XXX""" """XXX"""
@ -42,7 +42,7 @@ class GuiCanvasInterface():
self.parentCanvas.brushColours[0] = numColour self.parentCanvas.brushColours[0] = numColour
elif event.GetEventType() == wx.wxEVT_TOOL_RCLICKED: elif event.GetEventType() == wx.wxEVT_TOOL_RCLICKED:
self.parentCanvas.brushColours[1] = numColour self.parentCanvas.brushColours[1] = numColour
self.parentFrame.onCanvasUpdate(colours=self.parentCanvas.brushColours) self.parentFrame.update(colours=self.parentCanvas.brushColours)
# }}} # }}}
# {{{ canvasCopy(self, event): XXX # {{{ canvasCopy(self, event): XXX
def canvasCopy(self, event): def canvasCopy(self, event):
@ -82,10 +82,10 @@ class GuiCanvasInterface():
if newCanvasSize == None: if newCanvasSize == None:
newCanvasSize = list(self.parentCanvas.defaultCanvasSize) newCanvasSize = list(self.parentCanvas.defaultCanvasSize)
newMap = [[[1, 1, 0, " "] for x in range(newCanvasSize[0])] for y in range(newCanvasSize[1])] newMap = [[[1, 1, 0, " "] for x in range(newCanvasSize[0])] for y in range(newCanvasSize[1])]
self.parentCanvas.onStoreUpdate(newCanvasSize, newMap) self.parentCanvas.update(newCanvasSize, False, newMap)
self.canvasPathName = None self.canvasPathName = None
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
self.parentFrame.onCanvasUpdate(pathName="", undoLevel=-1) self.parentFrame.update(pathName="", undoLevel=-1)
# }}} # }}}
# {{{ canvasOpen(self, event): XXX # {{{ canvasOpen(self, event): XXX
def canvasOpen(self, event): def canvasOpen(self, event):
@ -103,12 +103,11 @@ 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))
import pdb; pdb.set_trace() rc, error = self.parentCanvas.canvas.importStore.importTextFile(self.canvasPathName)
rc, error = self.parentCanvas.canvasImportStore.importTextFile(self.canvasPathName)
if rc: if rc:
self.parentCanvas.onStoreUpdate(self.parentCanvas.canvasImportStore.inSize, self.parentCanvas.canvasImportStore.outMap) self.parentCanvas.update(self.parentCanvas.canvas.importStore.inSize, False, self.parentCanvas.canvas.importStore.outMap)
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
self.parentFrame.onCanvasUpdate(pathName=self.canvasPathName, undoLevel=-1) self.parentFrame.update(pathName=self.canvasPathName, undoLevel=-1)
return True return True
else: else:
print("error: {}".format(error), file=sys.stderr) print("error: {}".format(error), file=sys.stderr)
@ -120,7 +119,8 @@ class GuiCanvasInterface():
# }}} # }}}
# {{{ canvasRedo(self, event): XXX # {{{ canvasRedo(self, event): XXX
def canvasRedo(self, event): def canvasRedo(self, event):
self.parentCanvas._dispatchDeltaPatches(self.parentCanvas.canvasJournal.popRedo()) self.parentCanvas.dispatchDeltaPatches(self.parentCanvas.canvas.journal.popRedo())
self.parentFrame.update(size=self.parentCanvas.canvas.size, undoLevel=self.parentCanvas.canvas.journal.patchesUndoLevel)
# }}} # }}}
# {{{ canvasSave(self, event): XXX # {{{ canvasSave(self, event): XXX
def canvasSave(self, event): def canvasSave(self, event):
@ -130,8 +130,8 @@ class GuiCanvasInterface():
try: try:
with open(self.canvasPathName, "w", encoding="utf-8") as outFile: with open(self.canvasPathName, "w", encoding="utf-8") as outFile:
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
self.parentCanvas.canvasExportStore.exportTextFile( \ self.parentCanvas.canvas.exportStore.exportTextFile( \
self.parentCanvas.canvasMap, self.parentCanvas.canvasSize, outFile) self.parentCanvas.canvas.map, self.parentCanvas.canvas.size, outFile)
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
return True return True
except IOError as error: except IOError as error:
@ -148,14 +148,15 @@ class GuiCanvasInterface():
# }}} # }}}
# {{{ canvasUndo(self, event): XXX # {{{ canvasUndo(self, event): XXX
def canvasUndo(self, event): def canvasUndo(self, event):
self.parentCanvas._dispatchDeltaPatches(self.parentCanvas.canvasJournal.popUndo()) self.parentCanvas.dispatchDeltaPatches(self.parentCanvas.canvas.journal.popUndo())
self.parentFrame.update(size=self.parentCanvas.canvas.size, undoLevel=self.parentCanvas.canvas.journal.patchesUndoLevel)
# }}} # }}}
# {{{ 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:
self.parentCanvas.brushSize[1] -= 1 self.parentCanvas.brushSize[1] -= 1
self.parentFrame.onCanvasUpdate(brushSize=self.parentCanvas.brushSize) self.parentFrame.update(brushSize=self.parentCanvas.brushSize)
# }}} # }}}
# {{{ canvasDecrBrushHeightWidth(self, event): XXX # {{{ canvasDecrBrushHeightWidth(self, event): XXX
def canvasDecrBrushHeightWidth(self, event): def canvasDecrBrushHeightWidth(self, event):
@ -166,12 +167,12 @@ class GuiCanvasInterface():
def canvasDecrBrushWidth(self, event): def canvasDecrBrushWidth(self, event):
if self.parentCanvas.brushSize[0] > 1: if self.parentCanvas.brushSize[0] > 1:
self.parentCanvas.brushSize[0] -= 1 self.parentCanvas.brushSize[0] -= 1
self.parentFrame.onCanvasUpdate(brushSize=self.parentCanvas.brushSize) self.parentFrame.update(brushSize=self.parentCanvas.brushSize)
# }}} # }}}
# {{{ 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.canvas.size[1] > 1:
self.parentCanvas.resize([self.parentCanvas.canvasSize[0], self.parentCanvas.canvasSize[1] - 1]) self.parentCanvas.resize([self.parentCanvas.canvas.size[0], self.parentCanvas.canvas.size[1] - 1])
# }}} # }}}
# {{{ canvasDecrCanvasHeightWidth(self, event): XXX # {{{ canvasDecrCanvasHeightWidth(self, event): XXX
def canvasDecrCanvasHeightWidth(self, event): def canvasDecrCanvasHeightWidth(self, event):
@ -180,13 +181,13 @@ 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.canvas.size[0] > 1:
self.parentCanvas.resize([self.parentCanvas.canvasSize[0] - 1, self.parentCanvas.canvasSize[1]]) self.parentCanvas.resize([self.parentCanvas.canvas.size[0] - 1, self.parentCanvas.canvas.size[1]])
# }}} # }}}
# {{{ canvasIncrBrushHeight(self, event): XXX # {{{ canvasIncrBrushHeight(self, event): XXX
def canvasIncrBrushHeight(self, event): def canvasIncrBrushHeight(self, event):
self.parentCanvas.brushSize[1] += 1 self.parentCanvas.brushSize[1] += 1
self.parentFrame.onCanvasUpdate(brushSize=self.parentCanvas.brushSize) self.parentFrame.update(brushSize=self.parentCanvas.brushSize)
# }}} # }}}
# {{{ canvasIncrBrushHeightWidth(self, event): XXX # {{{ canvasIncrBrushHeightWidth(self, event): XXX
def canvasIncrBrushHeightWidth(self, event): def canvasIncrBrushHeightWidth(self, event):
@ -196,11 +197,11 @@ class GuiCanvasInterface():
# {{{ canvasIncrBrushWidth(self, event): XXX # {{{ canvasIncrBrushWidth(self, event): XXX
def canvasIncrBrushWidth(self, event): def canvasIncrBrushWidth(self, event):
self.parentCanvas.brushSize[0] += 1 self.parentCanvas.brushSize[0] += 1
self.parentFrame.onCanvasUpdate(brushSize=self.parentCanvas.brushSize) self.parentFrame.update(brushSize=self.parentCanvas.brushSize)
# }}} # }}}
# {{{ canvasIncrCanvasHeight(self, event): XXX # {{{ canvasIncrCanvasHeight(self, event): XXX
def canvasIncrCanvasHeight(self, event): def canvasIncrCanvasHeight(self, event):
self.parentCanvas.resize([self.parentCanvas.canvasSize[0], self.parentCanvas.canvasSize[1] + 1]) self.parentCanvas.resize([self.parentCanvas.canvas.size[0], self.parentCanvas.canvas.size[1] + 1])
# }}} # }}}
# {{{ canvasIncrCanvasHeightWidth(self, event): XXX # {{{ canvasIncrCanvasHeightWidth(self, event): XXX
def canvasIncrCanvasHeightWidth(self, event): def canvasIncrCanvasHeightWidth(self, event):
@ -209,7 +210,7 @@ class GuiCanvasInterface():
# }}} # }}}
# {{{ canvasIncrCanvasWidth(self, event): XXX # {{{ canvasIncrCanvasWidth(self, event): XXX
def canvasIncrCanvasWidth(self, event): def canvasIncrCanvasWidth(self, event):
self.parentCanvas.resize([self.parentCanvas.canvasSize[0] + 1, self.parentCanvas.canvasSize[1]]) self.parentCanvas.resize([self.parentCanvas.canvas.size[0] + 1, self.parentCanvas.canvas.size[1]])
# }}} # }}}
# {{{ canvasExportAsAnsi(self, event): XXX # {{{ canvasExportAsAnsi(self, event): XXX
@ -221,7 +222,7 @@ class GuiCanvasInterface():
outPathName = dialog.GetPath() outPathName = dialog.GetPath()
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
with open(outPathName, "w", encoding="utf-8") as outFile: with open(outPathName, "w", encoding="utf-8") as outFile:
self.parentCanvas.canvasExportStore.exportAnsiFile(self.parentCanvas.canvasMap, self.parentCanvas.canvasSize, outFile) self.parentCanvas.canvas.exportStore.exportAnsiFile(self.parentCanvas.canvas.map, self.parentCanvas.canvas.size, outFile)
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
return True return True
# }}} # }}}
@ -233,7 +234,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.canvas.exportStore.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
@ -241,7 +242,7 @@ 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))
rc, status, result = self.parentCanvas.canvasExportStore.exportBitmapToImgur( \ rc, status, result = self.parentCanvas.canvas.exportStore.exportBitmapToImgur( \
self.imgurApiKey, self.parentCanvas.canvasBackend.canvasBitmap, "", "", wx.BITMAP_TYPE_PNG) self.imgurApiKey, self.parentCanvas.canvasBackend.canvasBitmap, "", "", wx.BITMAP_TYPE_PNG)
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
if rc: if rc:
@ -254,11 +255,7 @@ class GuiCanvasInterface():
# {{{ 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.canvas.exportStore.exportPastebin("", self.parentCanvas.canvas.map, self.parentCanvas.canvas.size)
self.parentCanvas.canvasExportStore.exportPastebin( \
"", \
self.parentCanvas.canvasMap, \
self.parentCanvas.canvasSize)
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
if pasteStatus: if pasteStatus:
if not wx.TheClipboard.IsOpened(): if not wx.TheClipboard.IsOpened():
@ -272,7 +269,7 @@ class GuiCanvasInterface():
# {{{ canvasExportToClipboard(self, event): XXX # {{{ canvasExportToClipboard(self, event): XXX
def canvasExportToClipboard(self, event): def canvasExportToClipboard(self, event):
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
rc, outBuffer = self.parentCanvas.canvasExportStore.exportTextBuffer(self.parentCanvas.canvasMap, self.parentCanvas.canvasSize) rc, outBuffer = self.parentCanvas.canvas.exportStore.exportTextBuffer(self.parentCanvas.canvas.map, self.parentCanvas.canvas.size)
if rc and wx.TheClipboard.Open(): if rc and wx.TheClipboard.Open():
wx.TheClipboard.SetData(wx.TextDataObject(outBuffer)) wx.TheClipboard.SetData(wx.TextDataObject(outBuffer))
wx.TheClipboard.Close() wx.TheClipboard.Close()
@ -295,12 +292,12 @@ 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))
rc, error = self.parentCanvas.canvasImportStore.importAnsiFile(self.canvasPathName) rc, error = self.parentCanvas.canvas.importStore.importAnsiFile(self.canvasPathName)
if rc: if rc:
self.parentCanvas.onStoreUpdate(self.parentCanvas.canvasImportStore.inSize, self.parentCanvas.canvasImportStore.outMap) self.parentCanvas.update(self.parentCanvas.canvas.importStore.inSize, False, self.parentCanvas.canvas.importStore.outMap)
self.canvasPathName = "(Imported)" self.canvasPathName = "(Imported)"
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
self.parentFrame.onCanvasUpdate(pathName="(Imported)", undoLevel=-1) self.parentFrame.update(pathName="(Imported)", undoLevel=-1)
return True return True
else: else:
print("error: {}".format(error), file=sys.stderr) print("error: {}".format(error), file=sys.stderr)
@ -322,12 +319,12 @@ 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))
rc, error = self.parentCanvas.canvasImportStore.importTextBuffer(io.StringIO(inBuffer.GetText())) rc, error = self.parentCanvas.canvas.importStore.importTextBuffer(io.StringIO(inBuffer.GetText()))
if rc: if rc:
self.parentCanvas.onStoreUpdate(self.parentCanvas.canvasImportStore.inSize, self.parentCanvas.canvasImportStore.outMap) self.parentCanvas.update(self.parentCanvas.canvas.importStore.inSize, False, self.parentCanvas.canvas.importStore.outMap)
self.canvasPathName = "(Clipboard)" self.canvasPathName = "(Clipboard)"
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
self.parentFrame.onCanvasUpdate(pathName="(Clipboard)", undoLevel=-1) self.parentFrame.update(pathName="(Clipboard)", undoLevel=-1)
else: else:
print("error: {}".format(error), file=sys.stderr) print("error: {}".format(error), file=sys.stderr)
wx.TheClipboard.Close() wx.TheClipboard.Close()
@ -351,12 +348,12 @@ 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))
rc, error = self.parentCanvas.canvasImportStore.importSauceFile(self.canvasPathName) rc, error = self.parentCanvas.canvas.importStore.importSauceFile(self.canvasPathName)
if rc: if rc:
self.parentCanvas.onStoreUpdate(self.parentCanvas.canvasImportStore.inSize, self.parentCanvas.canvasImportStore.outMap) self.parentCanvas.update(self.parentCanvas.canvas.importStore.inSize, False, self.parentCanvas.canvas.importStore.outMap)
self.canvasPathName = "(Imported)" self.canvasPathName = "(Imported)"
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
self.parentFrame.onCanvasUpdate(pathName="(Imported)", undoLevel=-1) self.parentFrame.update(pathName="(Imported)", undoLevel=-1)
return True return True
else: else:
print("error: {}".format(error), file=sys.stderr) print("error: {}".format(error), file=sys.stderr)
@ -369,7 +366,7 @@ class GuiCanvasInterface():
self.parentFrame.menuItemsById[self.parentFrame.CID_CIRCLE[0]].Check(True) self.parentFrame.menuItemsById[self.parentFrame.CID_CIRCLE[0]].Check(True)
toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_CIRCLE[0]].GetToolBar() toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_CIRCLE[0]].GetToolBar()
toolBar.ToggleTool(self.parentFrame.CID_CIRCLE[0], True) toolBar.ToggleTool(self.parentFrame.CID_CIRCLE[0], True)
self.parentFrame.onCanvasUpdate(toolName=self.canvasTool.name) self.parentFrame.update(toolName=self.canvasTool.name)
# }}} # }}}
# {{{ canvasToolFill(self, event): XXX # {{{ canvasToolFill(self, event): XXX
def canvasToolFill(self, event): def canvasToolFill(self, event):
@ -377,7 +374,7 @@ class GuiCanvasInterface():
self.parentFrame.menuItemsById[self.parentFrame.CID_FILL[0]].Check(True) self.parentFrame.menuItemsById[self.parentFrame.CID_FILL[0]].Check(True)
toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_FILL[0]].GetToolBar() toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_FILL[0]].GetToolBar()
toolBar.ToggleTool(self.parentFrame.CID_FILL[0], True) toolBar.ToggleTool(self.parentFrame.CID_FILL[0], True)
self.parentFrame.onCanvasUpdate(toolName=self.canvasTool.name) self.parentFrame.update(toolName=self.canvasTool.name)
# }}} # }}}
# {{{ canvasToolLine(self, event): XXX # {{{ canvasToolLine(self, event): XXX
def canvasToolLine(self, event): def canvasToolLine(self, event):
@ -385,7 +382,7 @@ class GuiCanvasInterface():
self.parentFrame.menuItemsById[self.parentFrame.CID_LINE[0]].Check(True) self.parentFrame.menuItemsById[self.parentFrame.CID_LINE[0]].Check(True)
toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_LINE[0]].GetToolBar() toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_LINE[0]].GetToolBar()
toolBar.ToggleTool(self.parentFrame.CID_LINE[0], True) toolBar.ToggleTool(self.parentFrame.CID_LINE[0], True)
self.parentFrame.onCanvasUpdate(toolName=self.canvasTool.name) self.parentFrame.update(toolName=self.canvasTool.name)
# }}} # }}}
# {{{ canvasToolSelectClone(self, event): XXX # {{{ canvasToolSelectClone(self, event): XXX
def canvasToolSelectClone(self, event): def canvasToolSelectClone(self, event):
@ -393,7 +390,7 @@ class GuiCanvasInterface():
self.parentFrame.menuItemsById[self.parentFrame.CID_CLONE_SELECT[0]].Check(True) self.parentFrame.menuItemsById[self.parentFrame.CID_CLONE_SELECT[0]].Check(True)
toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_CLONE_SELECT[0]].GetToolBar() toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_CLONE_SELECT[0]].GetToolBar()
toolBar.ToggleTool(self.parentFrame.CID_CLONE_SELECT[0], True) toolBar.ToggleTool(self.parentFrame.CID_CLONE_SELECT[0], True)
self.parentFrame.onCanvasUpdate(toolName=self.canvasTool.name) self.parentFrame.update(toolName=self.canvasTool.name)
# }}} # }}}
# {{{ canvasToolSelectMove(self, event): XXX # {{{ canvasToolSelectMove(self, event): XXX
def canvasToolSelectMove(self, event): def canvasToolSelectMove(self, event):
@ -401,7 +398,7 @@ class GuiCanvasInterface():
self.parentFrame.menuItemsById[self.parentFrame.CID_MOVE_SELECT[0]].Check(True) self.parentFrame.menuItemsById[self.parentFrame.CID_MOVE_SELECT[0]].Check(True)
toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_MOVE_SELECT[0]].GetToolBar() toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_MOVE_SELECT[0]].GetToolBar()
toolBar.ToggleTool(self.parentFrame.CID_MOVE_SELECT[0], True) toolBar.ToggleTool(self.parentFrame.CID_MOVE_SELECT[0], True)
self.parentFrame.onCanvasUpdate(toolName=self.canvasTool.name) self.parentFrame.update(toolName=self.canvasTool.name)
# }}} # }}}
# {{{ canvasToolRect(self, event): XXX # {{{ canvasToolRect(self, event): XXX
def canvasToolRect(self, event): def canvasToolRect(self, event):
@ -409,7 +406,7 @@ class GuiCanvasInterface():
self.parentFrame.menuItemsById[self.parentFrame.CID_RECT[0]].Check(True) self.parentFrame.menuItemsById[self.parentFrame.CID_RECT[0]].Check(True)
toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_RECT[0]].GetToolBar() toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_RECT[0]].GetToolBar()
toolBar.ToggleTool(self.parentFrame.CID_RECT[0], True) toolBar.ToggleTool(self.parentFrame.CID_RECT[0], True)
self.parentFrame.onCanvasUpdate(toolName=self.canvasTool.name) self.parentFrame.update(toolName=self.canvasTool.name)
# }}} # }}}
# {{{ canvasToolText(self, event): XXX # {{{ canvasToolText(self, event): XXX
def canvasToolText(self, event): def canvasToolText(self, event):
@ -417,7 +414,7 @@ class GuiCanvasInterface():
self.parentFrame.menuItemsById[self.parentFrame.CID_TEXT[0]].Check(True) self.parentFrame.menuItemsById[self.parentFrame.CID_TEXT[0]].Check(True)
toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_TEXT[0]].GetToolBar() toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_TEXT[0]].GetToolBar()
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.update(toolName=self.canvasTool.name)
# }}} # }}}
# #

133
libgui/GuiCanvasPanel.py Normal file
View File

@ -0,0 +1,133 @@
#!/usr/bin/env python3
#
# GuiCanvasPanel.py -- XXX
# Copyright (c) 2018, 2019 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
#
import wx
class GuiCanvasPanel(wx.Panel):
"""XXX"""
# {{{ _drawPatch(self, eventDc, isCursor, patch): XXX
def _drawPatch(self, eventDc, isCursor, patch):
if not self.canvas.dirtyCursor:
self.backend.drawCursorMaskWithJournal(self.canvas.journal, eventDc)
self.canvas.dirtyCursor = True
if self.backend.drawPatch(eventDc, patch) \
and isCursor:
patchDeltaCell = self.canvas.map[patch[1]][patch[0]]; patchDelta = [*patch[0:2], *patchDeltaCell];
self.canvas.journal.pushCursor(patchDelta)
# }}}
# {{{ dispatchDeltaPatches(self, deltaPatches): XXX
def dispatchDeltaPatches(self, deltaPatches):
eventDc = self.backend.getDeviceContext(self)
for patch in deltaPatches:
if patch == None:
continue
elif patch[0] == "resize":
del eventDc; self.resize(patch[1:], False); eventDc = self.backend.getDeviceContext(self);
else:
self.canvas._commitPatch(patch); self.backend.drawPatch(eventDc, patch);
# }}}
# {{{ dispatchPatch(self, eventDc, isCursor, patch): XXX
def dispatchPatch(self, eventDc, isCursor, patch):
self.canvas.dispatchPatch(isCursor, patch, False if isCursor else True)
self._drawPatch(eventDc, isCursor, patch)
# }}}
# {{{ resize(self, newSize, commitUndo=True): XXX
def resize(self, newSize, commitUndo=True):
oldSize = [0, 0] if self.canvas.map == None else self.canvas.size
deltaSize = [b - a for a, b in zip(oldSize, newSize)]
if self.canvas.resize(newSize, commitUndo):
newWinSize = [a * b for a, b in zip(newSize, self.backend.cellSize)]
self.SetMinSize(newWinSize); self.SetSize(wx.DefaultCoord, wx.DefaultCoord, *newWinSize);
curWindow = self
while curWindow != None:
curWindow.Layout(); curWindow = curWindow.GetParent();
self.backend.resize(newSize, self.backend.cellSize)
eventDc = self.backend.getDeviceContext(self)
if deltaSize[0] > 0:
for numRow in range(oldSize[1]):
for numNewCol in range(oldSize[0], newSize[0]):
self._drawPatch(eventDc, False, [numNewCol, numRow, 1, 1, 0, " "])
if deltaSize[1] > 1:
for numNewRow in range(oldSize[1], newSize[1]):
for numNewCol in range(newSize[0]):
self._drawPatch(eventDc, False, [numNewCol, numNewRow, 1, 1, 0, " "])
del eventDc; wx.SafeYield();
self.parentFrame.update(size=newSize, undoLevel=self.canvas.journal.patchesUndoLevel)
# }}}
# {{{ update(self, newSize, commitUndo=True, newCanvas=None): XXX
def update(self, newSize, commitUndo=True, newCanvas=None):
self.resize(newSize, commitUndo)
self.canvas.update(newSize, newCanvas)
eventDc = self.backend.getDeviceContext(self)
for numRow in range(newSize[1]):
for numCol in range(newSize[0]):
self.backend.drawPatch(eventDc, [numCol, numRow, *self.canvas.map[numRow][numCol]])
wx.SafeYield()
# }}}
# {{{ onPanelClose(self, event): XXX
def onPanelClose(self, event):
self.Destroy()
# }}}
# {{{ onPanelEnterWindow(self, event): XXX
def onPanelEnterWindow(self, event):
self.parentFrame.SetFocus()
# }}}
# {{{ onPanelInput(self, event): XXX
def onPanelInput(self, event):
self.canvas.dirty, self.canvas.dirtyCursor = False, False
eventDc, eventType, tool = self.backend.getDeviceContext(self), event.GetEventType(), self.interface.canvasTool
if eventType == wx.wxEVT_CHAR:
mapPoint = self.brushPos
doSkip = tool.onKeyboardEvent(event, mapPoint, self.brushColours, self.brushSize, chr(event.GetUnicodeKey()), self.dispatchPatch, eventDc)
if doSkip:
event.Skip(); return;
else:
mapPoint = self.backend.xlateEventPoint(event, eventDc)
if mapPoint[0] >= self.canvas.size[0] \
or mapPoint[1] >= self.canvas.size[1]:
return
self.brushPos = mapPoint
tool.onMouseEvent( \
event, mapPoint, self.brushColours, self.brushSize, \
event.Dragging(), event.LeftIsDown(), event.RightIsDown(), \
self.dispatchPatch, eventDc)
if self.canvas.dirty:
self.parentFrame.update(cellPos=self.brushPos, undoLevel=self.canvas.journal.patchesUndoLevel)
if eventType == wx.wxEVT_MOTION:
self.parentFrame.update(cellPos=mapPoint)
# }}}
# {{{ onPanelLeaveWindow(self, event): XXX
def onPanelLeaveWindow(self, event):
eventDc = self.backend.getDeviceContext(self)
self.backend.drawCursorMaskWithJournal(self.canvas.journal, eventDc)
# }}}
# {{{ onPanelPaint(self, event): XXX
def onPanelPaint(self, event):
self.backend.onPanelPaintEvent(event, self)
# }}}
#
# __init__(self, parent, parentFrame, backend, canvas, defaultCanvasPos, defaultCanvasSize, defaultCellSize, interface): initialisation method
def __init__(self, parent, parentFrame, backend, canvas, defaultCanvasPos, defaultCanvasSize, defaultCellSize, interface):
super().__init__(parent, pos=defaultCanvasPos, size=[w * h for w, h in zip(defaultCanvasSize, defaultCellSize)])
self.backend, self.interface = backend(defaultCanvasSize, defaultCellSize), interface(self, parentFrame)
self.brushColours, self.brushPos, self.brushSize = [4, 1], [0, 0], [1, 1]
self.canvas, self.canvasPos, self.defaultCanvasPos, self.defaultCanvasSize, self.defaultCellSize = canvas, defaultCanvasPos, defaultCanvasPos, defaultCanvasSize, defaultCellSize
self.parentFrame = parentFrame
self.parentFrame.update(brushSize=self.brushSize, colours=self.brushColours)
self.Bind(wx.EVT_CLOSE, self.onPanelClose)
self.Bind(wx.EVT_ENTER_WINDOW, self.onPanelEnterWindow)
self.Bind(wx.EVT_LEAVE_WINDOW, self.onPanelLeaveWindow)
self.parentFrame.Bind(wx.EVT_CHAR, self.onPanelInput)
for eventType in (wx.EVT_LEFT_DOWN, wx.EVT_MOTION, wx.EVT_RIGHT_DOWN):
self.Bind(eventType, self.onPanelInput)
self.Bind(wx.EVT_PAINT, self.onPanelPaint)
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=0

View File

@ -1,13 +1,13 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# #
# CanvasBackend.py -- XXX # GuiCanvasWxBackend.py -- XXX
# Copyright (c) 2018, 2019 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de> # Copyright (c) 2018, 2019 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
# #
from CanvasColours import Colours from GuiCanvasColours import Colours
import wx import wx
class CanvasBackend(): class GuiCanvasWxBackend():
"""XXX""" """XXX"""
# {{{ _drawBrushPatch(self, eventDc, patch): XXX # {{{ _drawBrushPatch(self, eventDc, patch): XXX

View File

@ -4,9 +4,12 @@
# Copyright (c) 2018, 2019 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de> # Copyright (c) 2018, 2019 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
# #
from Canvas import Canvas, haveUrllib from Canvas import Canvas
from CanvasColours import Colours from CanvasExportStore import haveUrllib
from GuiCanvasColours import Colours
from GuiCanvasInterface import GuiCanvasInterface from GuiCanvasInterface import GuiCanvasInterface
from GuiCanvasPanel import GuiCanvasPanel
from GuiCanvasWxBackend import GuiCanvasWxBackend
from GuiGeneralFrame import GuiGeneralFrame, \ from GuiGeneralFrame import GuiGeneralFrame, \
TID_ACCELS, TID_COMMAND, TID_LIST, TID_MENU, TID_NOTHING, TID_SELECT, TID_TOOLBAR, \ TID_ACCELS, TID_COMMAND, TID_LIST, TID_MENU, TID_NOTHING, TID_SELECT, TID_TOOLBAR, \
NID_MENU_SEP, NID_TOOLBAR_HSEP, NID_TOOLBAR_VSEP NID_MENU_SEP, NID_TOOLBAR_HSEP, NID_TOOLBAR_VSEP
@ -116,9 +119,7 @@ class GuiFrame(GuiGeneralFrame):
def _initIcon(self): def _initIcon(self):
iconPathNames = glob(os.path.join("assets", "images", "logo*.bmp")) iconPathNames = glob(os.path.join("assets", "images", "logo*.bmp"))
iconPathName = iconPathNames[random.randint(0, len(iconPathNames) - 1)] iconPathName = iconPathNames[random.randint(0, len(iconPathNames) - 1)]
icon = wx.Icon() icon = wx.Icon(); icon.CopyFromBitmap(wx.Bitmap(iconPathName, wx.BITMAP_TYPE_ANY)); self.SetIcon(icon);
icon.CopyFromBitmap(wx.Bitmap(iconPathName, wx.BITMAP_TYPE_ANY))
self.SetIcon(icon)
# }}} # }}}
# {{{ _initPaletteToolBitmaps(self): XXX # {{{ _initPaletteToolBitmaps(self): XXX
def _initPaletteToolBitmaps(self): def _initPaletteToolBitmaps(self):
@ -131,8 +132,7 @@ class GuiFrame(GuiGeneralFrame):
toolBitmapColour = Colours[numColour][0:4] toolBitmapColour = Colours[numColour][0:4]
toolBitmap = wx.Bitmap((16,16)) toolBitmap = wx.Bitmap((16,16))
toolBitmapDc = wx.MemoryDC(); toolBitmapDc.SelectObject(toolBitmap); toolBitmapDc = wx.MemoryDC(); toolBitmapDc.SelectObject(toolBitmap);
toolBitmapBrush = wx.Brush( \ toolBitmapBrush = wx.Brush(wx.Colour(toolBitmapColour), wx.BRUSHSTYLE_SOLID)
wx.Colour(toolBitmapColour), wx.BRUSHSTYLE_SOLID)
toolBitmapDc.SetBrush(toolBitmapBrush) toolBitmapDc.SetBrush(toolBitmapBrush)
toolBitmapDc.SetBackground(toolBitmapBrush) toolBitmapDc.SetBackground(toolBitmapBrush)
toolBitmapDc.SetPen(wx.Pen(wx.Colour(toolBitmapColour), 1)) toolBitmapDc.SetPen(wx.Pen(wx.Colour(toolBitmapColour), 1))
@ -140,35 +140,18 @@ class GuiFrame(GuiGeneralFrame):
paletteDescr[numColour][4] = ["", None, toolBitmap] paletteDescr[numColour][4] = ["", None, toolBitmap]
# }}} # }}}
# {{{ onInput(self, event): XXX # {{{ update(self, **kwargs): XXX
def onInput(self, event): def update(self, **kwargs):
eventId = event.GetId() self.lastPanelState.update(kwargs); textItems = [];
if eventId >= self.CID_COLOUR00[0] \
and eventId <= self.CID_COLOUR15[0]:
numColour = eventId - self.CID_COLOUR00[0]
self.itemsById[eventId][7](self.panelCanvas.canvasInterface, event, numColour)
else:
self.itemsById[eventId][7](self.panelCanvas.canvasInterface, event)
# }}}
# {{{ onCanvasUpdate(self, newBrushSize=None, newCellPos=None, newColours=None, newPathName=None, newSize=None, newToolName=None, newUndoLevel=None): XXX
def onCanvasUpdate(self, **kwargs):
self.lastPanelState.update(kwargs)
textItems = []
if "cellPos" in self.lastPanelState: if "cellPos" in self.lastPanelState:
textItems.append("X: {:03d} Y: {:03d}".format( \ textItems.append("X: {:03d} Y: {:03d}".format(*self.lastPanelState["cellPos"]))
*self.lastPanelState["cellPos"]))
if "size" in self.lastPanelState: if "size" in self.lastPanelState:
textItems.append("W: {:03d} H: {:03d}".format( \ textItems.append("W: {:03d} H: {:03d}".format(*self.lastPanelState["size"]))
*self.lastPanelState["size"]))
if "brushSize" in self.lastPanelState: if "brushSize" in self.lastPanelState:
textItems.append("Brush: {:02d}x{:02d}".format( \ textItems.append("Brush: {:02d}x{:02d}".format(*self.lastPanelState["brushSize"]))
*self.lastPanelState["brushSize"]))
if "colours" in self.lastPanelState: if "colours" in self.lastPanelState:
textItems.append("FG: {:02d}, BG: {:02d}".format( \ textItems.append("FG: {:02d}, BG: {:02d}".format(*self.lastPanelState["colours"]))
*self.lastPanelState["colours"])) textItems.append("{} on {}".format(Colours[self.lastPanelState["colours"][0]][4], Colours[self.lastPanelState["colours"][1]][4]))
textItems.append("{} on {}".format( \
Colours[self.lastPanelState["colours"][0]][4], \
Colours[self.lastPanelState["colours"][1]][4]))
if "pathName" in self.lastPanelState: if "pathName" in self.lastPanelState:
if self.lastPanelState["pathName"] != "": if self.lastPanelState["pathName"] != "":
basePathName = os.path.basename(self.lastPanelState["pathName"]) basePathName = os.path.basename(self.lastPanelState["pathName"])
@ -177,8 +160,7 @@ class GuiFrame(GuiGeneralFrame):
else: else:
self.SetTitle("roar") self.SetTitle("roar")
if "toolName" in self.lastPanelState: if "toolName" in self.lastPanelState:
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:
@ -198,11 +180,15 @@ class GuiFrame(GuiGeneralFrame):
toolBar = self.toolBarItemsById[self.CID_REDO[0]].GetToolBar() toolBar = self.toolBarItemsById[self.CID_REDO[0]].GetToolBar()
toolBar.EnableTool(self.CID_REDO[0], False) toolBar.EnableTool(self.CID_REDO[0], False)
# }}} # }}}
# {{{ onInput(self, event): XXX
# {{{ __del__(self): destructor method def onInput(self, event):
def __del__(self): eventId = event.GetId()
if self.panelCanvas != None: if eventId >= self.CID_COLOUR00[0] \
del self.panelCanvas; self.panelCanvas = None; and eventId <= self.CID_COLOUR15[0]:
numColour = eventId - self.CID_COLOUR00[0]
self.itemsById[eventId][7](self.canvasPanel.interface, event, numColour)
else:
self.itemsById[eventId][7](self.canvasPanel.interface, event)
# }}} # }}}
# #
@ -210,18 +196,15 @@ class GuiFrame(GuiGeneralFrame):
def __init__(self, parent, appSize=(840, 630), defaultCanvasPos=(0, 75), defaultCanvasSize=(100, 30), defaultCellSize=(7, 14)): def __init__(self, parent, appSize=(840, 630), defaultCanvasPos=(0, 75), defaultCanvasSize=(100, 30), defaultCellSize=(7, 14)):
self._initPaletteToolBitmaps() self._initPaletteToolBitmaps()
self.panelSkin = super().__init__(parent, wx.ID_ANY, "", size=appSize) self.panelSkin = super().__init__(parent, wx.ID_ANY, "", size=appSize)
self.lastPanelState, self.panelCanvas = {}, None self.lastPanelState, self.canvasPanel = {}, None
self._initIcon() self._initIcon()
self.panelCanvas = Canvas(self.panelSkin, parentFrame=self, \ self.canvas = Canvas(defaultCanvasSize)
canvasInterface=GuiCanvasInterface, \ self.canvasPanel = GuiCanvasPanel(self.panelSkin, self, GuiCanvasWxBackend, self.canvas, defaultCanvasPos, defaultCanvasSize, defaultCellSize, GuiCanvasInterface)
defaultCanvasPos=defaultCanvasPos, \ self.canvasPanel.interface.canvasNew(None)
defaultCanvasSize=defaultCanvasSize, \
defaultCellSize=defaultCellSize)
self.panelCanvas.canvasInterface.canvasNew(None)
self.sizerSkin.AddSpacer(5) self.sizerSkin.AddSpacer(5)
self.sizerSkin.Add(self.panelCanvas, 0, wx.ALL|wx.EXPAND, 14) self.sizerSkin.Add(self.canvasPanel, 0, wx.ALL|wx.EXPAND, 14)
self.panelSkin.SetSizer(self.sizerSkin) self.panelSkin.SetSizer(self.sizerSkin)
self.panelSkin.SetAutoLayout(1) self.panelSkin.SetAutoLayout(1)
self.sizerSkin.Fit(self.panelSkin) self.sizerSkin.Fit(self.panelSkin)

View File

@ -14,24 +14,24 @@ class ToolFill(Tool):
# onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): XXX # onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): XXX
def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc):
pointStack, pointsDone = [list(atPoint)], [] pointStack, pointsDone = [list(atPoint)], []
testColour = self.parentCanvas.canvasMap[atPoint[1]][atPoint[0]][0:2] testColour = self.parentCanvas.canvas.map[atPoint[1]][atPoint[0]][0:2]
if isLeftDown or isRightDown: if isLeftDown or isRightDown:
if isRightDown: if isRightDown:
brushColours = [brushColours[1], brushColours[0]] brushColours = [brushColours[1], brushColours[0]]
while len(pointStack) > 0: while len(pointStack) > 0:
point = pointStack.pop() point = pointStack.pop()
pointCell = self.parentCanvas.canvasMap[point[1]][point[0]] pointCell = self.parentCanvas.canvas.map[point[1]][point[0]]
if pointCell[0:2] == testColour: if (pointCell[0:2] == testColour) \
or ((pointCell[3] == " ") and (pointCell[1] == testColour[1])):
if not point in pointsDone: if not point in pointsDone:
dispatchFn(eventDc, False, [*point, \ dispatchFn(eventDc, False, [*point, brushColours[0], brushColours[0], 0, " "])
brushColours[0], brushColours[0], 0, " "])
if point[0] > 0: if point[0] > 0:
pointStack.append([point[0] - 1, point[1]]) pointStack.append([point[0] - 1, point[1]])
if point[0] < (self.parentCanvas.canvasSize[0] - 1): if point[0] < (self.parentCanvas.canvas.size[0] - 1):
pointStack.append([point[0] + 1, point[1]]) pointStack.append([point[0] + 1, point[1]])
if point[1] > 0: if point[1] > 0:
pointStack.append([point[0], point[1] - 1]) pointStack.append([point[0], point[1] - 1])
if point[1] < (self.parentCanvas.canvasSize[1] - 1): if point[1] < (self.parentCanvas.canvas.size[1] - 1):
pointStack.append([point[0], point[1] + 1]) pointStack.append([point[0], point[1] + 1])
pointsDone += [point] pointsDone += [point]

View File

@ -64,7 +64,7 @@ class ToolSelect(Tool):
self.toolSelectMap.append([]) self.toolSelectMap.append([])
for numCol in range((self.targetRect[1][0] - self.targetRect[0][0]) + 1): for numCol in range((self.targetRect[1][0] - self.targetRect[0][0]) + 1):
rectX, rectY = self.targetRect[0][0] + numCol, self.targetRect[0][1] + numRow rectX, rectY = self.targetRect[0][0] + numCol, self.targetRect[0][1] + numRow
self.toolSelectMap[numRow].append(self.parentCanvas.canvasMap[rectY][rectX]) self.toolSelectMap[numRow].append(self.parentCanvas.canvas.map[rectY][rectX])
self._drawSelectRect(self.targetRect, dispatchFn, eventDc) self._drawSelectRect(self.targetRect, dispatchFn, eventDc)
elif isRightDown: elif isRightDown:
self.targetRect, self.toolState = None, self.TS_NONE self.targetRect, self.toolState = None, self.TS_NONE

View File

@ -24,9 +24,9 @@ class ToolText(Tool):
if self.textPos == None: if self.textPos == None:
self.textPos = list(atPoint) self.textPos = list(atPoint)
dispatchFn(eventDc, False, [*self.textPos, *self.textColours, 0, keyChar]) dispatchFn(eventDc, False, [*self.textPos, *self.textColours, 0, keyChar])
if self.textPos[0] < (self.parentCanvas.canvasSize[0] - 1): if self.textPos[0] < (self.parentCanvas.canvas.size[0] - 1):
self.textPos[0] += 1 self.textPos[0] += 1
elif self.textPos[1] < (self.parentCanvas.canvasSize[1] - 1): elif self.textPos[1] < (self.parentCanvas.canvas.size[1] - 1):
self.textPos[0] = 0; self.textPos[1] += 1; self.textPos[0] = 0; self.textPos[1] += 1;
else: else:
self.textPos = [0, 0] self.textPos = [0, 0]

View File

@ -18,11 +18,11 @@ def main(*argv):
appFrame = GuiFrame(None) appFrame = GuiFrame(None)
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.canvasPanel.interface.canvasPathName = argv[1]
rc, error = appFrame.panelCanvas.canvasImportStore.importTextFile(argv[1]) rc, error = appFrame.canvasPanel.canvas.importStore.importTextFile(argv[1])
if rc: if rc:
appFrame.panelCanvas.onStoreUpdate(appFrame.panelCanvas.canvasImportStore.inSize, appFrame.panelCanvas.canvasImportStore.outMap) appFrame.canvasPanel.update(appFrame.canvasPanel.canvas.importStore.inSize, False, appFrame.canvasPanel.canvas.importStore.outMap)
appFrame.onCanvasUpdate(pathName=argv[1], undoLevel=-1) appFrame.update(pathName=argv[1], undoLevel=-1)
else: else:
print("error: {}".format(error), file=sys.stderr) print("error: {}".format(error), file=sys.stderr)
wxApp.MainLoop() wxApp.MainLoop()