Various bugfixes & usability improvements.

1)  Add background colour toolbar beneath (foreground) colour toolbar.
2)  Add colour flipping command w/ {accelerator,{menu,toolbar} item}.
3)  Add {de,in}crease {brush,canvas} size accelerator.
4)  Add {hide,show} assets window toolbar item.
5)  Circle tool: draw outline with foreground colour.
6)  Circle tool: honour transparency.
7)  Fill tool: change comprehensive fill modifier key from <Shift> to <Ctrl>.
8)  Fill tool: fill with {back,fore}ground colour given <[RL]MB>
9)  Fix arrow keys cursor motion when scrolled down.
10  Instantly reflect {brush size,colour,tool} changes in canvas.
11) Object tool: honour transparency w/ non-external objects.
12) Object tool: update selection rectangle during <LMB> whilst dragging, set w/ release of <LMB>.
13) Rectangle tool: draw outline with foreground colour.
14) Rectangle tool: honour transparency.
15) Replace wx.ToolBar() w/ wx.lib.agw.aui.AuiToolBar() & custom wx.lib.agw.aui.AuiDefaultToolBarArt().
16) Restore scrolling position after resizing canvas.

.TODO: deleted.
assets/audio/roar{arab8,spoke11}.wav: added.
assets/text/hotkeys.txt: added to document hotkeys.
assets/text/requirements.txt, requirements.txt: moved.
assets/text/TODO: updated.
{assets/tools,lib{canvas,gui,roar,rtl,tools}}/*.py: remove Vim fold markers.
libroar/RoarCanvasCommandsFile.py:_importFile(): update wx.FileDialog() message.
libroar/RoarCanvasCommandsOperators.py:canvasOperator(): update invert colours {caption,label}.
This commit is contained in:
Lucio Andrés Illanes Albornoz 2019-09-23 18:49:33 +02:00
parent 14d3560b70
commit ced45fa0d4
38 changed files with 488 additions and 523 deletions

1
.TODO
View File

@ -1 +0,0 @@
text bug: a) select text tool b) paste stuff c) undo d) artifacts

BIN
assets/audio/roararab8.wav Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 B

View File

@ -1,26 +1,29 @@
Low-priority list: 1) Finish Arabic/RTL text tool support
1) Implement ANSI CSI CU[BDPU] sequences & italic 2) ANSI CSI CU[BDPU] sequences & italic
2) Layers & layout (e.g. for comics, zines, etc.) 3) Operators: crop, scale, shift, slice
3) Implement instrumentation & unit tests, document 4) Documentation, instrumentation & unit tests
4) Open and toggle a reference image in the background 5) Layers & layout (e.g. for comics, zines, etc.)
5) Client-Server or Peer-to-Peer realtime collaboration 6) Open and toggle a reference image in the background
6) Arbitrary {format,palette}s ({4,8} bit ANSI/mIRC, etc.) 7) Client-Server or Peer-to-Peer realtime collaboration
7) {record,replay} {keyboard,mouse,...} events in debugging builds 8) Arbitrary {format,palette}s ({4,8} bit ANSI/mIRC, etc.)
8) Incremental auto{load,save} & {backup,restore} (needs Settings window) 9) {record,replay} {keyboard,mouse,...} events in debugging builds
9) Composition, parametrisation & keying of tools from higher-order operators (brushes, functions, filters, outlines, patterns & shaders) and unit tools 10) Incremental auto{load,save} & {backup,restore} (needs Settings window)
10) Sprites & scripted (Python?) animation on the basis of asset traits and {composable,parametrised} patterns (metric flow, particle system, rigging, ...) 11) Unit tools: arrow, {cloud,speech bubble}, curve, measure, polygon, triangle
11) Integrate ENNTool code in the form of OpenGL-based animation window (see 9) and 10)) 12) Integrate ENNTool code in the form of OpenGL-based animation window (see 13) and 14))
13) Composition, parametrisation & keying of tools from higher-order operators (brushes, functions, filters, outlines, patterns & shaders) and unit tools
High-priority list: 14) Sprites & scripted (Python?) animation on the basis of asset traits and {composable,parametrised} patterns (metric flow, particle system, rigging, ...)
1) unit tools: arrow, {cloud,speech bubble}, curve, measure, pick, polygon, triangle, unicode 15) GUI TODO list:
2) operators: rotate, scale, shift, slice, tile
3) cleanup & refactor, switch to GTK
4) GUI:
a) replace logo w/ canvas panel in About dialogue a) replace logo w/ canvas panel in About dialogue
b) purge MRU list menu item, remove files from MRU list if inaccessible b) purge MRU list menu item, remove files from MRU list if inaccessible
c) Settings/Settings window (e.g. autosave, hide cursor on leaving window, ...) c) Settings/Settings window (e.g. autosave, hide cursor on leaving window, ...)
d) replace resize buttons w/ {-,edit box,+} buttons & lock button re: ratio (ty lol3) d) replace resize buttons w/ {-,edit box,+} buttons & lock button re: ratio (ty lol3)
e) {copy,cut,delete,insert from,paste}, {edit asset in new canvas,import from {canvas,object}} e) {copy,cut,delete,insert from,paste}, {edit asset in new canvas,import from {canvas,object}}
5) finish Arabic/RTL text implementation
High-priority list:
1) a) select line tool b) set origin point c) move mouse about d) incr brush size e) set target point d) undo
a) new canvas/startup b) place rect c) move mouse d) undo status changes
a) text tool b) paste text c) undo
2) add hotkeys.txt mIRC art canvas to help menu
2) tools: erase, pick, unicode block elements
vim:ff=dos tw=0 vim:ff=dos tw=0

15
assets/text/hotkeys.txt Normal file
View File

@ -0,0 +1,15 @@
<Ctrl> 0-9, <Ctrl> <Shift> 0-5, <Ctrl> <Shift> 6 Set foreground colour to #0-9, #10-15, transparent colour, resp.
<Ctrl> <Alt> 0-9, <Ctrl> <Alt> <Shift> 0-5, <Ctrl> <Alt> <Shift> 6 Set background colour to #0-9, #10-15, transparent colour, resp.
<Ctrl> C U F L R E T Switch to circle, cursor, fill, line, rectangle, object, text tool
<Ctrl> I Flip colours
<Ctrl> N New canvas
<Ctrl> O Open mIRC art file
<Ctrl> S Save canvas as mIRC art file
<Ctrl> X Exit
<Ctrl> Y, Z Redo, undo, resp.
<Shift> <Pause> Break into Python debugger
(Canvas) <Down>, <Left>, <Right>, <Up> Move canvas cursor
(Canvas) <Left mouse button>, <Space> Apply current tool with foreground colour or initiate tool action (line and object tool)
(Canvas) <Right mouse button> Apply current tool with background colour
(Fill tool) <Ctrl> <Left mouse button>, <Right mouse button> Fill entire region ignoring character cells
(Object tool) <Ctrl> <Left mouse button> Move selection instead of cloning

View File

@ -0,0 +1 @@
.

View File

@ -19,17 +19,14 @@ class IrcMiRCARTBot(IrcClient):
"""IRC<->MiRC2png bot""" """IRC<->MiRC2png bot"""
imgurApiKey = ImgurApiKey.imgurApiKey imgurApiKey = ImgurApiKey.imgurApiKey
# {{{ ContentTooLargeException(Exception): Raised by _urlretrieveReportHook() given download size > 1 MB
class ContentTooLargeException(Exception): class ContentTooLargeException(Exception):
pass pass
# }}}
# {{{ _dispatch001(self, message): Dispatch single 001 (RPL_WELCOME)
def _dispatch001(self, message): def _dispatch001(self, message):
self._log("Registered on {}:{} as {}, {}, {}.".format(self.serverHname, self.serverPort, self.clientNick, self.clientIdent, self.clientGecos)) self._log("Registered on {}:{} as {}, {}, {}.".format(self.serverHname, self.serverPort, self.clientNick, self.clientIdent, self.clientGecos))
self._log("Attempting to join {} on {}:{}...".format(self.clientChannel, self.serverHname, self.serverPort)) self._log("Attempting to join {} on {}:{}...".format(self.clientChannel, self.serverHname, self.serverPort))
self.queue("JOIN", self.clientChannel) self.queue("JOIN", self.clientChannel)
# }}}
# {{{ _dispatch353(self, message): Dispatch single 353 (RPL_NAMREPLY)
def _dispatch353(self, message): def _dispatch353(self, message):
if message[4].lower() == self.clientChannel.lower(): if message[4].lower() == self.clientChannel.lower():
for channelNickSpec in message[5].split(" "): for channelNickSpec in message[5].split(" "):
@ -38,20 +35,17 @@ class IrcMiRCARTBot(IrcClient):
and len(channelNickSpec[1:]): and len(channelNickSpec[1:]):
self.clientChannelOps.append(channelNickSpec[1:].lower()) self.clientChannelOps.append(channelNickSpec[1:].lower())
self._log("Authorising {} on {}".format(channelNickSpec[1:].lower(), message[4].lower())) self._log("Authorising {} on {}".format(channelNickSpec[1:].lower(), message[4].lower()))
# }}}
# {{{ _dispatchJoin(self, message): Dispatch single JOIN message from server
def _dispatchJoin(self, message): def _dispatchJoin(self, message):
self._log("Joined {} on {}:{}.".format(message[2].lower(), self.serverHname, self.serverPort)) self._log("Joined {} on {}:{}.".format(message[2].lower(), self.serverHname, self.serverPort))
self.clientNextTimeout = None; self.clientChannelRejoin = False; self.clientNextTimeout = None; self.clientChannelRejoin = False;
# }}}
# {{{ _dispatchKick(self, message): Dispatch single KICK message from server
def _dispatchKick(self, message): def _dispatchKick(self, message):
if message[2].lower() == self.clientChannel.lower() \ if message[2].lower() == self.clientChannel.lower() \
and message[3].lower() == self.clientNick.lower(): and message[3].lower() == self.clientNick.lower():
self._log("Kicked from {} by {}, rejoining in 15 seconds".format(message[2].lower(), message[0])) self._log("Kicked from {} by {}, rejoining in 15 seconds".format(message[2].lower(), message[0]))
self.clientNextTimeout = time.time() + 15; self.clientChannelRejoin = True; self.clientNextTimeout = time.time() + 15; self.clientChannelRejoin = True;
# }}}
# {{{ _dispatchMode(self, message): Dispatch single MODE message from server
def _dispatchMode(self, message): def _dispatchMode(self, message):
if message[2].lower() == self.clientChannel.lower(): if message[2].lower() == self.clientChannel.lower():
channelModeType = "+"; channelModeArg = 4; channelModeType = "+"; channelModeArg = 4;
@ -78,17 +72,14 @@ class IrcMiRCARTBot(IrcClient):
channelAuthDel = channelAuthDel.lower() channelAuthDel = channelAuthDel.lower()
self._log("Deauthorising {} on {}".format(channelAuthDel, message[2].lower())) self._log("Deauthorising {} on {}".format(channelAuthDel, message[2].lower()))
self.clientChannelOps.remove(channelAuthDel) self.clientChannelOps.remove(channelAuthDel)
# }}}
# {{{ _dispatchNone(self): Dispatch None message from server
def _dispatchNone(self): def _dispatchNone(self):
self._log("Disconnected from {}:{}.".format(self.serverHname, self.serverPort)) self._log("Disconnected from {}:{}.".format(self.serverHname, self.serverPort))
self.close() self.close()
# }}}
# {{{ _dispatchPing(self, message): Dispatch single PING message from server
def _dispatchPing(self, message): def _dispatchPing(self, message):
self.queue("PONG", message[2]) self.queue("PONG", message[2])
# }}}
# {{{ _dispatchPrivmsg(self, message): Dispatch single PRIVMSG message from server
def _dispatchPrivmsg(self, message): def _dispatchPrivmsg(self, message):
if message[2].lower() == self.clientChannel.lower() \ if message[2].lower() == self.clientChannel.lower() \
and message[3].startswith("!pngbot "): and message[3].startswith("!pngbot "):
@ -155,19 +146,16 @@ class IrcMiRCARTBot(IrcClient):
os.remove(asciiTmpFilePath) os.remove(asciiTmpFilePath)
if os.path.isfile(imgTmpFilePath): if os.path.isfile(imgTmpFilePath):
os.remove(imgTmpFilePath) os.remove(imgTmpFilePath)
# }}}
# {{{ _dispatchTimer(self): Dispatch single client timer expiration
def _dispatchTimer(self): def _dispatchTimer(self):
if self.clientChannelRejoin: if self.clientChannelRejoin:
self._log("Attempting to join {} on {}:{}...".format(self.clientChannel, self.serverHname, self.serverPort)) self._log("Attempting to join {} on {}:{}...".format(self.clientChannel, self.serverHname, self.serverPort))
self.queue("JOIN", self.clientChannel) self.queue("JOIN", self.clientChannel)
self.clientNextTimeout = time.time() + 15; self.clientChannelRejoin = True; self.clientNextTimeout = time.time() + 15; self.clientChannelRejoin = True;
# }}}
# {{{ _log(self, msg): Log single message to stdout w/ timestamp
def _log(self, msg): def _log(self, msg):
print(time.strftime("%Y/%m/%d %H:%M:%S") + " " + msg) print(time.strftime("%Y/%m/%d %H:%M:%S") + " " + msg)
# }}}
# {{{ _uploadToImgur(self, imgFilePath, imgName, imgTitle, apiKey): Upload single file to Imgur
def _uploadToImgur(self, imgFilePath, imgName, imgTitle, apiKey): def _uploadToImgur(self, imgFilePath, imgName, imgTitle, apiKey):
with open(imgFilePath, "rb") as requestImage: with open(imgFilePath, "rb") as requestImage:
requestImageData = requestImage.read() requestImageData = requestImage.read()
@ -188,13 +176,11 @@ class IrcMiRCARTBot(IrcClient):
return [200, responseDict.get("data").get("link")] return [200, responseDict.get("data").get("link")]
else: else:
return [responseHttp.status_code, responseHttp.text] return [responseHttp.status_code, responseHttp.text]
# }}}
# {{{ _urlretrieveReportHook(count, blockSize, totalSize): Limit downloads to 1 MB
def _urlretrieveReportHook(count, blockSize, totalSize): def _urlretrieveReportHook(count, blockSize, totalSize):
if (totalSize > pow(2,20)): if (totalSize > pow(2,20)):
raise IrcMiRCARTBot.ContentTooLargeException raise IrcMiRCARTBot.ContentTooLargeException
# }}}
# {{{ connect(self, localAddr=None, preferFamily=0, timeout=None): Connect to server and (re)initialise w/ optional timeout
def connect(self, localAddr=None, preferFamily=0, timeout=None): def connect(self, localAddr=None, preferFamily=0, timeout=None):
self._log("Connecting to {}:{}...".format(self.serverHname, self.serverPort)) self._log("Connecting to {}:{}...".format(self.serverHname, self.serverPort))
if super().connect(localAddr=localAddr, preferFamily=preferFamily, timeout=timeout): if super().connect(localAddr=localAddr, preferFamily=preferFamily, timeout=timeout):
@ -206,8 +192,7 @@ class IrcMiRCARTBot(IrcClient):
return True return True
else: else:
return False return False
# }}}
# {{{ dispatch(self): Read, parse, and dispatch single line from server
def dispatch(self): def dispatch(self):
while True: while True:
if self.clientNextTimeout: if self.clientNextTimeout:
@ -245,7 +230,7 @@ class IrcMiRCARTBot(IrcClient):
self.clientHasPing = False self.clientHasPing = False
elif serverMessage[1] == "PRIVMSG": elif serverMessage[1] == "PRIVMSG":
self._dispatchPrivmsg(serverMessage) self._dispatchPrivmsg(serverMessage)
# }}}
# #
# __init__(self, serverHname, serverPort="6667", clientNick="pngbot", clientIdent="pngbot", clientGecos="pngbot", clientChannel="#MiRCART"): initialisation method # __init__(self, serverHname, serverPort="6667", clientNick="pngbot", clientIdent="pngbot", clientGecos="pngbot", clientChannel="#MiRCART"): initialisation method

View File

@ -9,12 +9,10 @@ from CanvasImportStore import CanvasImportStore
from CanvasJournal import CanvasJournal from CanvasJournal import CanvasJournal
class Canvas(): class Canvas():
# {{{ _commitPatch(self, patch)
def _commitPatch(self, patch): def _commitPatch(self, patch):
self.map[patch[1]][patch[0]] = patch[2:] self.map[patch[1]][patch[0]] = patch[2:]
# }}}
# {{{ dispatchPatch(self, isCursor, patch, commitUndo=True)
def dispatchPatch(self, isCursor, patch, commitUndo=True): def dispatchPatch(self, isCursor, patch, commitUndo=True):
if (patch[0] >= self.size[0]) or (patch[1] >= self.size[1]): if (patch[0] >= self.size[0]) or (patch[1] >= self.size[1]):
return False return False
@ -27,8 +25,7 @@ class Canvas():
self.journal.begin(); self.journal.updateCurrentDeltas(patch, patchDelta); self.journal.end(); self.journal.begin(); self.journal.updateCurrentDeltas(patch, patchDelta); self.journal.end();
self._commitPatch(patch) self._commitPatch(patch)
return True return True
# }}}
# {{{ dispatchPatchSingle(self, isCursor, patch, commitUndo=True)
def dispatchPatchSingle(self, isCursor, patch, commitUndo=True): def dispatchPatchSingle(self, isCursor, patch, commitUndo=True):
if (patch[0] >= self.size[0]) or (patch[1] >= self.size[1]): if (patch[0] >= self.size[0]) or (patch[1] >= self.size[1]):
return False return False
@ -41,8 +38,7 @@ class Canvas():
self.journal.updateCurrentDeltas(patch, patchDelta) self.journal.updateCurrentDeltas(patch, patchDelta)
self._commitPatch(patch) self._commitPatch(patch)
return True return True
# }}}
# {{{ resize(self, newSize, commitUndo=True)
def resize(self, newSize, commitUndo=True): def resize(self, newSize, commitUndo=True):
if newSize != self.size: if newSize != self.size:
if self.map == None: if self.map == None:
@ -87,8 +83,7 @@ class Canvas():
return True return True
else: else:
return False return False
# }}}
# {{{ update(self, newSize, newCanvas=None)
def update(self, newSize, newCanvas=None): def update(self, newSize, newCanvas=None):
for numRow in range(self.size[1]): for numRow in range(self.size[1]):
for numCol in range(self.size[0]): for numCol in range(self.size[0]):
@ -96,7 +91,7 @@ class Canvas():
and (numRow < len(newCanvas)) \ and (numRow < len(newCanvas)) \
and (numCol < len(newCanvas[numRow])): and (numCol < len(newCanvas[numRow])):
self._commitPatch([numCol, numRow, *newCanvas[numRow][numCol]]) self._commitPatch([numCol, numRow, *newCanvas[numRow][numCol]])
# }}}
# #
# __init__(self, size): initialisation method # __init__(self, size): initialisation method

View File

@ -4,7 +4,6 @@
# Copyright (c) 2018, 2019 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de> # Copyright (c) 2018, 2019 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
# #
# {{{ AnsiBgToMiRCARTColours
AnsiBgToMiRCARTColours = { AnsiBgToMiRCARTColours = {
107: 0, # Bright White 107: 0, # Bright White
40: 1, # Black 40: 1, # Black
@ -23,8 +22,7 @@ AnsiBgToMiRCARTColours = {
100: 14, # Grey 100: 14, # Grey
47: 15, # Light Grey 47: 15, # Light Grey
}; };
# }}}
# {{{ AnsiFgBoldToMiRCARTColours
AnsiFgBoldToMiRCARTColours = { AnsiFgBoldToMiRCARTColours = {
97: 0, # Bright White 97: 0, # Bright White
30: 14, # Grey 30: 14, # Grey
@ -43,8 +41,7 @@ AnsiFgBoldToMiRCARTColours = {
90: 14, # Grey 90: 14, # Grey
37: 0, # Bright White 37: 0, # Bright White
}; };
# }}}
# {{{ AnsiFgToMiRCARTColours
AnsiFgToMiRCARTColours = { AnsiFgToMiRCARTColours = {
97: 0, # Bright White 97: 0, # Bright White
30: 1, # Black 30: 1, # Black
@ -63,8 +60,7 @@ AnsiFgToMiRCARTColours = {
90: 14, # Grey 90: 14, # Grey
37: 15, # Light Grey 37: 15, # Light Grey
}; };
# }}}
# {{{ ColourMapBold: mIRC colour number to RGBA map given ^B (bold)
ColourMapBold = [ ColourMapBold = [
[255, 255, 255], # Bright White [255, 255, 255], # Bright White
[85, 85, 85], # Black [85, 85, 85], # Black
@ -83,8 +79,7 @@ ColourMapBold = [
[85, 85, 85], # Grey [85, 85, 85], # Grey
[255, 255, 255], # Light Grey [255, 255, 255], # Light Grey
] ]
# }}}
# {{{ ColourMapNormal: mIRC colour number to RGBA map given none of ^[BFV_] (bold, italic, reverse, underline)
ColourMapNormal = [ ColourMapNormal = [
[255, 255, 255], # Bright White [255, 255, 255], # Bright White
[0, 0, 0], # Black [0, 0, 0], # Black
@ -103,8 +98,7 @@ ColourMapNormal = [
[85, 85, 85], # Grey [85, 85, 85], # Grey
[187, 187, 187], # Light Grey [187, 187, 187], # Light Grey
] ]
# }}}
# {{{ MiRCARTToAnsiColours
MiRCARTToAnsiColours = [ MiRCARTToAnsiColours = [
97, # Bright White 97, # Bright White
30, # Black 30, # Black
@ -123,6 +117,6 @@ MiRCARTToAnsiColours = [
90, # Grey 90, # Grey
37, # Light Grey 37, # Light Grey
]; ];
# }}}
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 # vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -20,25 +20,22 @@ except ImportError:
haveUrllib = False haveUrllib = False
class CanvasExportStore(): class CanvasExportStore():
# {{{ _CellState(): Cell state
class _CellState(): class _CellState():
CS_NONE = 0x00 CS_NONE = 0x00
CS_BOLD = 0x01 CS_BOLD = 0x01
CS_ITALIC = 0x02 CS_ITALIC = 0x02
CS_UNDERLINE = 0x04 CS_UNDERLINE = 0x04
# }}}
ImgurUploadUrl = "https://api.imgur.com/3/upload.json" ImgurUploadUrl = "https://api.imgur.com/3/upload.json"
PastebinPostUrl = "https://pastebin.com/api/api_post.php" PastebinPostUrl = "https://pastebin.com/api/api_post.php"
# {{{ _drawUnderline(self, curPos, fillColour, fontSize, imgDraw)
def _drawUnderLine(self, curPos, fillColour, fontSize, imgDraw): def _drawUnderLine(self, curPos, fillColour, fontSize, imgDraw):
imgDraw.line( \ imgDraw.line( \
xy=(curPos[0], curPos[1] + (fontSize[1] - 2), \ xy=(curPos[0], curPos[1] + (fontSize[1] - 2), \
curPos[0] + fontSize[0], curPos[1] + (fontSize[1] - 2)), \ curPos[0] + fontSize[0], curPos[1] + (fontSize[1] - 2)), \
fill=fillColour) fill=fillColour)
# }}}
# {{{ exportAnsiFile(self, canvasMap, canvasSize, outFile)
def exportAnsiFile(self, canvasMap, canvasSize, outFile): def exportAnsiFile(self, canvasMap, canvasSize, outFile):
outBuffer = "" outBuffer = ""
for inCurRow in range(len(canvasMap)): for inCurRow in range(len(canvasMap)):
@ -71,8 +68,7 @@ class CanvasExportStore():
return (True, None) return (True, None)
else: else:
return (False, "empty buffer generated") return (False, "empty buffer generated")
# }}}
# {{{ exportBitmapToImgur(self, apiKey, canvasBitmap, imgName, imgTitle, imgType)
def exportBitmapToImgur(self, apiKey, canvasBitmap, imgName, imgTitle, imgType): def exportBitmapToImgur(self, apiKey, canvasBitmap, imgName, imgTitle, imgType):
tmpPathName = tempfile.mkstemp() tmpPathName = tempfile.mkstemp()
os.close(tmpPathName[0]) os.close(tmpPathName[0])
@ -94,12 +90,10 @@ class CanvasExportStore():
imgurResult = (False, responseHttp.status_code, responseDict.get("data")) imgurResult = (False, responseHttp.status_code, responseDict.get("data"))
os.remove(tmpPathName[1]) os.remove(tmpPathName[1])
return imgurResult return imgurResult
# }}}
# {{{ exportBitmapToPngFile(self, canvasBitmap, outPathName, outType)
def exportBitmapToPngFile(self, canvasBitmap, outPathName, outType): def exportBitmapToPngFile(self, canvasBitmap, outPathName, outType):
return canvasBitmap.ConvertToImage().SaveFile(outPathName, outType) return canvasBitmap.ConvertToImage().SaveFile(outPathName, outType)
# }}}
# {{{ exportPastebin(self, apiDevKey, canvasMap, canvasSize, pasteName="", pastePrivate=0)
def exportPastebin(self, apiDevKey, canvasMap, canvasSize, pasteName="", pastePrivate=0): def exportPastebin(self, apiDevKey, canvasMap, canvasSize, pasteName="", pastePrivate=0):
if haveUrllib: if haveUrllib:
outFile = io.StringIO() outFile = io.StringIO()
@ -117,8 +111,7 @@ class CanvasExportStore():
return (False, str(responseHttp.status_code)) return (False, str(responseHttp.status_code))
else: else:
return (False, "missing requests and/or urllib3 module(s)") return (False, "missing requests and/or urllib3 module(s)")
# }}}
# {{{ exportPngFile(self, canvasMap, fontFilePath, fontSize, outPathName)
def exportPngFile(self, canvasMap, fontFilePath, fontSize, outPathName): def exportPngFile(self, canvasMap, fontFilePath, fontSize, outPathName):
if havePIL: if havePIL:
inSize = (len(canvasMap[0]), len(canvasMap)) inSize = (len(canvasMap[0]), len(canvasMap))
@ -161,8 +154,7 @@ class CanvasExportStore():
return (True, None) return (True, None)
else: else:
return (False, "missing PIL modules") return (False, "missing PIL modules")
# }}}
# {{{ exportTextBuffer(self, canvasMap, canvasSize)
def exportTextBuffer(self, canvasMap, canvasSize): def exportTextBuffer(self, canvasMap, canvasSize):
outBuffer = "" outBuffer = ""
for canvasRow in range(canvasSize[1]): for canvasRow in range(canvasSize[1]):
@ -213,11 +205,10 @@ class CanvasExportStore():
return (True, outBuffer) return (True, outBuffer)
else: else:
return (False, "empty buffer generated") return (False, "empty buffer generated")
# }}}
# {{{ exportTextFile(self, canvasMap, canvasSize, outFile)
def exportTextFile(self, canvasMap, canvasSize, outFile): def exportTextFile(self, canvasMap, canvasSize, outFile):
rc, outBuffer = self.exportTextBuffer(canvasMap, canvasSize) rc, outBuffer = self.exportTextBuffer(canvasMap, canvasSize)
return outFile.write(outBuffer) if rc else (rc, outBuffer) return outFile.write(outBuffer) if rc else (rc, outBuffer)
# }}}
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 # vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -9,20 +9,17 @@ from CanvasColours import AnsiBgToMiRCARTColours, AnsiFgToMiRCARTColours, AnsiFg
import io, os, re, struct, sys import io, os, re, struct, sys
class CanvasImportStore(): class CanvasImportStore():
# {{{ _CellState(): Cell state
class _CellState(): class _CellState():
CS_NONE = 0x00 CS_NONE = 0x00
CS_BOLD = 0x01 CS_BOLD = 0x01
CS_ITALIC = 0x02 CS_ITALIC = 0x02
CS_UNDERLINE = 0x04 CS_UNDERLINE = 0x04
# }}}
# {{{ _flipCellStateBit(self, bit, cellState)
def _flipCellStateBit(self, bit, cellState): def _flipCellStateBit(self, bit, cellState):
return cellState & ~bit if cellState & bit else cellState | bit return cellState & ~bit if cellState & bit else cellState | bit
# }}}
# {{{ importAnsiBuffer(self, inBuffer, encoding="cp437", width=None)
def importAnsiBuffer(self, inBuffer, 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
@ -74,12 +71,10 @@ class CanvasImportStore():
return (True, None) return (True, None)
else: else:
return (False, "empty output map") return (False, "empty output map")
# }}}
# {{{ importAnsiFile(self, inPathName, encoding="cp437")
def importAnsiFile(self, inPathName, encoding="cp437"): def importAnsiFile(self, inPathName, encoding="cp437"):
return self.importAnsiBuffer(open(inPathName, "rb").read(), encoding) return self.importAnsiBuffer(open(inPathName, "rb").read(), encoding)
# }}}
# {{{ importSauceFile(self, inPathName, encoding="cp437")
def importSauceFile(self, inPathName, encoding="cp437"): def importSauceFile(self, inPathName, encoding="cp437"):
with open(inPathName, "rb") as inFile: with open(inPathName, "rb") as inFile:
inFileStat = os.stat(inPathName) inFileStat = os.stat(inPathName)
@ -90,8 +85,7 @@ class CanvasImportStore():
return self.importAnsiBuffer(inFileData, encoding, 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")
# }}}
# {{{ importTextBuffer(self, inFile)
def importTextBuffer(self, inFile): def importTextBuffer(self, inFile):
try: try:
inLine, outMap, outMaxCols = inFile.readline(), [], 0 inLine, outMap, outMaxCols = inFile.readline(), [], 0
@ -137,12 +131,11 @@ class CanvasImportStore():
return (False, "empty output map") return (False, "empty output map")
except: except:
return (False, sys.exc_info()[1]) return (False, sys.exc_info()[1])
# }}}
# {{{ importTextFile(self, pathName)
def importTextFile(self, pathName): def importTextFile(self, pathName):
with open(pathName, "r", encoding="utf-8-sig") as inFile: with open(pathName, "r", encoding="utf-8-sig") as inFile:
return self.importTextBuffer(inFile) return self.importTextBuffer(inFile)
# }}}
# #
# __init__(self, inFile=None): initialisation method # __init__(self, inFile=None): initialisation method

View File

@ -5,68 +5,58 @@
# #
class CanvasJournal(): class CanvasJournal():
# {{{ begin(self)
def begin(self): def begin(self):
deltaItem = [[], []]; self.patchesUndo.insert(self.patchesUndoLevel, deltaItem); deltaItem = [[], []]; self.patchesUndo.insert(self.patchesUndoLevel, deltaItem);
# }}}
# {{{ end(self)
def end(self): def end(self):
if self.patchesUndo[self.patchesUndoLevel] == [[], []]: if self.patchesUndo[self.patchesUndoLevel] == [[], []]:
del self.patchesUndo[self.patchesUndoLevel] del self.patchesUndo[self.patchesUndoLevel]
else: else:
if self.patchesUndoLevel > 0: if self.patchesUndoLevel > 0:
del self.patchesUndo[:self.patchesUndoLevel]; self.patchesUndoLevel = 0; del self.patchesUndo[:self.patchesUndoLevel]; self.patchesUndoLevel = 0;
# }}}
# {{{ popCursor(self)
def popCursor(self): def popCursor(self):
if len(self.patchesCursor): if len(self.patchesCursor):
patchesCursor = self.patchesCursor; self.patchesCursor = []; patchesCursor = self.patchesCursor; self.patchesCursor = [];
return patchesCursor return patchesCursor
else: else:
return [] return []
# }}}
# {{{ popRedo(self)
def popRedo(self): def popRedo(self):
if self.patchesUndoLevel > 0: if self.patchesUndoLevel > 0:
self.patchesUndoLevel -= 1; patches = self.patchesUndo[self.patchesUndoLevel]; self.patchesUndoLevel -= 1; patches = self.patchesUndo[self.patchesUndoLevel];
return patches[1] return patches[1]
else: else:
return [] return []
# }}}
# {{{ popUndo(self)
def popUndo(self): def popUndo(self):
if self.patchesUndo[self.patchesUndoLevel] != None: 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] return patches[0]
else: else:
return [] return []
# }}}
# {{{ pushCursor(self, patches)
def pushCursor(self, patches): def pushCursor(self, patches):
self.patchesCursor.append(patches) self.patchesCursor.append(patches)
# }}}
# {{{ resetCursor(self)
def resetCursor(self): def resetCursor(self):
if self.patchesCursor != None: if self.patchesCursor != None:
self.patchesCursor.clear() self.patchesCursor.clear()
self.patchesCursor = [] self.patchesCursor = []
# }}}
# {{{ resetUndo(self)
def resetUndo(self): def resetUndo(self):
if self.patchesUndo != None: if self.patchesUndo != None:
self.patchesUndo.clear() self.patchesUndo.clear()
self.patchesUndo = [None]; self.patchesUndoLevel = 0; self.patchesUndo = [None]; self.patchesUndoLevel = 0;
# }}}
# {{{ updateCurrentDeltas(self, redoPatches, undoPatches)
def updateCurrentDeltas(self, redoPatches, undoPatches): def updateCurrentDeltas(self, redoPatches, undoPatches):
self.patchesUndo[self.patchesUndoLevel][0].append(undoPatches) self.patchesUndo[self.patchesUndoLevel][0].append(undoPatches)
self.patchesUndo[self.patchesUndoLevel][1].append(redoPatches) self.patchesUndo[self.patchesUndoLevel][1].append(redoPatches)
# }}}
# {{{ __del__(self): destructor method
def __del__(self): def __del__(self):
self.resetCursor(); self.resetUndo(); self.resetCursor(); self.resetUndo();
# }}}
# #
# __init__(self): initialisation method # __init__(self): initialisation method

View File

@ -9,12 +9,10 @@ from GuiCanvasColours import Colours
import math, os, platform, wx import math, os, platform, wx
class GuiBufferedDC(wx.MemoryDC): class GuiBufferedDC(wx.MemoryDC):
# {{{ __del__(self)
def __del__(self): def __del__(self):
self.dc.Blit(0, 0, *self.viewSize, self, 0, 0) self.dc.Blit(0, 0, *self.viewSize, self, 0, 0)
self.SelectObject(wx.NullBitmap) self.SelectObject(wx.NullBitmap)
# }}}
# {{{ __init__(self, backend, buffer, clientSize, dc, viewRect)
def __init__(self, backend, buffer, clientSize, dc, viewRect): def __init__(self, backend, buffer, clientSize, dc, viewRect):
super().__init__() super().__init__()
canvasSize = [a - b for a, b in zip(backend.canvasSize, viewRect)] canvasSize = [a - b for a, b in zip(backend.canvasSize, viewRect)]
@ -24,10 +22,9 @@ class GuiBufferedDC(wx.MemoryDC):
viewSize = [m * n for m, n in zip(backend.cellSize, viewSize)] viewSize = [m * n for m, n in zip(backend.cellSize, viewSize)]
self.SelectObject(buffer); self.SetDeviceOrigin(*viewRect); self.SelectObject(buffer); self.SetDeviceOrigin(*viewRect);
self.dc, self.viewRect, self.viewSize = dc, viewRect, viewSize self.dc, self.viewRect, self.viewSize = dc, viewRect, viewSize
# }}}
class GuiCanvasWxBackend(): class GuiCanvasWxBackend():
# {{{ arabicShapes{}
arabicShapes = { arabicShapes = {
u'\u0621': (u'\uFE80'), u'\u0621': (u'\uFE80'),
u'\u0622': (u'\uFE81', None, None, u'\uFE82'), u'\u0622': (u'\uFE81', None, None, u'\uFE82'),
@ -67,23 +64,20 @@ class GuiCanvasWxBackend():
u'\u0649': (u'\uFEEF', None, None, u'\uFEF0'), u'\u0649': (u'\uFEEF', None, None, u'\uFEF0'),
u'\u064A': (u'\uFEF1', u'\uFEF3', u'\uFEF4', u'\uFEF2'), u'\u064A': (u'\uFEF1', u'\uFEF3', u'\uFEF4', u'\uFEF2'),
} }
# }}}
# {{{ _CellState(): Cell state
class _CellState(): class _CellState():
CS_NONE = 0x00 CS_NONE = 0x00
CS_BOLD = 0x01 CS_BOLD = 0x01
CS_ITALIC = 0x02 CS_ITALIC = 0x02
CS_UNDERLINE = 0x04 CS_UNDERLINE = 0x04
# }}}
# {{{ _drawBrushPatch(self, eventDc, patch, point)
def _drawBrushPatch(self, eventDc, patch, point): def _drawBrushPatch(self, eventDc, patch, point):
absPoint = self._xlatePoint(point) absPoint = self._xlatePoint(point)
brushBg, brushFg, pen = self._getBrushPatchColours(patch) brushBg, brushFg, pen = self._getBrushPatchColours(patch)
self._setBrushDc(brushBg, brushFg, eventDc, pen) self._setBrushDc(brushBg, brushFg, eventDc, pen)
eventDc.DrawRectangle(*absPoint, *self.cellSize) eventDc.DrawRectangle(*absPoint, *self.cellSize)
# }}}
# {{{ _drawCharPatch(self, eventDc, patch, point)
def _drawCharPatch(self, eventDc, patch, point): def _drawCharPatch(self, eventDc, patch, point):
absPoint, fontBitmap = self._xlatePoint(point), wx.Bitmap(*self.cellSize) absPoint, fontBitmap = self._xlatePoint(point), wx.Bitmap(*self.cellSize)
brushBg, brushFg, pen = self._getCharPatchColours(patch) brushBg, brushFg, pen = self._getCharPatchColours(patch)
@ -99,14 +93,12 @@ class GuiCanvasWxBackend():
if patch[3] != "_": if patch[3] != "_":
fontDc.DrawText(patch[3], 0, 0) fontDc.DrawText(patch[3], 0, 0)
eventDc.Blit(*absPoint, *self.cellSize, fontDc, 0, 0) eventDc.Blit(*absPoint, *self.cellSize, fontDc, 0, 0)
# }}}
# {{{ _finiBrushesAndPens(self)
def _finiBrushesAndPens(self): def _finiBrushesAndPens(self):
[brush.Destroy() for brush in self._brushes or []] [brush.Destroy() for brush in self._brushes or []]
[pen.Destroy() for pen in self._pens or []] [pen.Destroy() for pen in self._pens or []]
self._brushes, self._lastBrushBg, self._lastBrushFg, self._lastPen, self._pens = None, None, None, None, None self._brushes, self._lastBrushBg, self._lastBrushFg, self._lastPen, self._pens = None, None, None, None, None
# }}}
# {{{ _getBrushPatchColours(self, patch)
def _getBrushPatchColours(self, patch): def _getBrushPatchColours(self, patch):
if (patch[0] != -1) and (patch[1] != -1): if (patch[0] != -1) and (patch[1] != -1):
brushBg, brushFg, pen = self._brushes[patch[1]], self._brushes[patch[1]], self._pens[patch[1]] brushBg, brushFg, pen = self._brushes[patch[1]], self._brushes[patch[1]], self._pens[patch[1]]
@ -117,8 +109,7 @@ class GuiCanvasWxBackend():
elif patch[1] == -1: elif patch[1] == -1:
brushBg, brushFg, pen = self._brushAlpha, self._brushAlpha, self._penAlpha brushBg, brushFg, pen = self._brushAlpha, self._brushAlpha, self._penAlpha
return (brushBg, brushFg, pen) return (brushBg, brushFg, pen)
# }}}
# {{{ _getCharPatchColours(self, patch)
def _getCharPatchColours(self, patch): def _getCharPatchColours(self, patch):
if (patch[0] != -1) and (patch[1] != -1): if (patch[0] != -1) and (patch[1] != -1):
brushBg, brushFg, pen = self._brushes[patch[1]], self._brushes[patch[1]], self._pens[patch[1]] brushBg, brushFg, pen = self._brushes[patch[1]], self._brushes[patch[1]], self._pens[patch[1]]
@ -129,8 +120,7 @@ class GuiCanvasWxBackend():
elif patch[1] == -1: elif patch[1] == -1:
brushBg, brushFg, pen = self._brushAlpha, self._brushAlpha, self._penAlpha brushBg, brushFg, pen = self._brushAlpha, self._brushAlpha, self._penAlpha
return (brushBg, brushFg, pen) return (brushBg, brushFg, pen)
# }}}
# {{{ _initBrushesAndPens(self)
def _initBrushesAndPens(self): def _initBrushesAndPens(self):
self._brushes, self._pens = [None for x in range(len(Colours))], [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)): for mircColour in range(len(Colours)):
@ -139,8 +129,7 @@ class GuiCanvasWxBackend():
self._brushAlpha = wx.Brush(wx.Colour(Colours[14][:4]), wx.BRUSHSTYLE_SOLID) self._brushAlpha = wx.Brush(wx.Colour(Colours[14][:4]), wx.BRUSHSTYLE_SOLID)
self._penAlpha = wx.Pen(wx.Colour(Colours[14][:4]), 1) self._penAlpha = wx.Pen(wx.Colour(Colours[14][:4]), 1)
self._lastBrushBg, self._lastBrushFg, self._lastPen = None, None, None self._lastBrushBg, self._lastBrushFg, self._lastPen = None, None, None
# }}}
# {{{ _reshapeArabic(self, canvas, eventDc, patch, point)
def _reshapeArabic(self, canvas, eventDc, patch, point): def _reshapeArabic(self, canvas, eventDc, patch, point):
lastCell = point[0] lastCell = point[0]
while True: while True:
@ -173,8 +162,7 @@ class GuiCanvasWxBackend():
else: else:
runCell[3] = self.arabicShapes[patch[5]][0] runCell[3] = self.arabicShapes[patch[5]][0]
self._drawCharPatch(eventDc, runCell, [point[0], point[1]]) self._drawCharPatch(eventDc, runCell, [point[0], point[1]])
# }}}
# {{{ _setBrushDc(self, brushBg, brushFg, dc, pen)
def _setBrushDc(self, brushBg, brushFg, dc, pen): def _setBrushDc(self, brushBg, brushFg, dc, pen):
if self._lastBrushBg != brushBg: if self._lastBrushBg != brushBg:
dc.SetBackground(brushBg); self._lastBrushBg = brushBg; dc.SetBackground(brushBg); self._lastBrushBg = brushBg;
@ -182,17 +170,14 @@ class GuiCanvasWxBackend():
dc.SetBrush(brushFg); self._lastBrushFg = brushFg; dc.SetBrush(brushFg); self._lastBrushFg = brushFg;
if self._lastPen != pen: if self._lastPen != pen:
dc.SetPen(pen); self._lastPen = pen; dc.SetPen(pen); self._lastPen = pen;
# }}}
# {{{ _xlatePoint(self, point)
def _xlatePoint(self, point): def _xlatePoint(self, point):
return [a * b for a, b in zip(point, self.cellSize)] return [a * b for a, b in zip(point, self.cellSize)]
# }}}
# {{{ drawCursorMaskWithJournal(self, canvas, canvasJournal, eventDc)
def drawCursorMaskWithJournal(self, canvas, canvasJournal, eventDc): def drawCursorMaskWithJournal(self, canvas, canvasJournal, eventDc):
[self.drawPatch(canvas, eventDc, patch) for patch in canvasJournal.popCursor()] [self.drawPatch(canvas, eventDc, patch) for patch in canvasJournal.popCursor()]
# }}}
# {{{ drawPatch(self, canvas, eventDc, patch)
def drawPatch(self, canvas, eventDc, patch): def drawPatch(self, canvas, eventDc, patch):
point = patch[:2] point = patch[:2]
if [(c >= 0) and (c < s) for c, s in zip(point, self.canvasSize)] == [True, True]: if [(c >= 0) and (c < s) for c, s in zip(point, self.canvasSize)] == [True, True]:
@ -210,8 +195,7 @@ class GuiCanvasWxBackend():
return True return True
else: else:
return False return False
# }}}
# {{{ getDeviceContext(self, clientSize, parentWindow, viewRect=None)
def getDeviceContext(self, clientSize, parentWindow, viewRect=None): def getDeviceContext(self, clientSize, parentWindow, viewRect=None):
if viewRect == None: if viewRect == None:
viewRect = parentWindow.GetViewStart() viewRect = parentWindow.GetViewStart()
@ -221,16 +205,14 @@ class GuiCanvasWxBackend():
eventDc = GuiBufferedDC(self, self.canvasBitmap, clientSize, wx.ClientDC(parentWindow), viewRect) eventDc = GuiBufferedDC(self, self.canvasBitmap, clientSize, wx.ClientDC(parentWindow), viewRect)
self._lastBrushBg, self._lastBrushFg, self._lastPen = None, None, None self._lastBrushBg, self._lastBrushFg, self._lastPen = None, None, None
return eventDc return eventDc
# }}}
# {{{ onPaint(self, clientSize, panelWindow, viewRect)
def onPaint(self, clientSize, panelWindow, viewRect): def onPaint(self, clientSize, panelWindow, viewRect):
if self.canvasBitmap != None: if self.canvasBitmap != None:
if viewRect == (0, 0): if viewRect == (0, 0):
eventDc = wx.BufferedPaintDC(panelWindow, self.canvasBitmap) eventDc = wx.BufferedPaintDC(panelWindow, self.canvasBitmap)
else: else:
eventDc = GuiBufferedDC(self, self.canvasBitmap, clientSize, wx.PaintDC(panelWindow), viewRect) eventDc = GuiBufferedDC(self, self.canvasBitmap, clientSize, wx.PaintDC(panelWindow), viewRect)
# }}}
# {{{ resize(self, canvasSize, cellSize):
def resize(self, canvasSize, cellSize): def resize(self, canvasSize, cellSize):
winSize = [a * b for a, b in zip(canvasSize, cellSize)] winSize = [a * b for a, b in zip(canvasSize, cellSize)]
if self.canvasBitmap == None: if self.canvasBitmap == None:
@ -246,21 +228,19 @@ class GuiCanvasWxBackend():
self._font = wx.TheFontList.FindOrCreateFont(cellSize[0] + 1, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, self.fontName) self._font = wx.TheFontList.FindOrCreateFont(cellSize[0] + 1, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, self.fontName)
else: else:
self._font = wx.Font(cellSize[0] + 1, wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL) self._font = wx.Font(cellSize[0] + 1, wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
# }}}
# {{{ xlateEventPoint(self, event, eventDc, viewRect)
def xlateEventPoint(self, event, eventDc, viewRect): def xlateEventPoint(self, event, eventDc, viewRect):
eventPoint = event.GetLogicalPosition(eventDc) eventPoint = event.GetLogicalPosition(eventDc)
rectX, rectY = eventPoint.x - (eventPoint.x % self.cellSize[0]), eventPoint.y - (eventPoint.y % self.cellSize[1]) 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) mapX, mapY = int(rectX / self.cellSize[0] if rectX else 0), int(rectY / self.cellSize[1] if rectY else 0)
return [m + n for m, n in zip((mapX, mapY), viewRect)] return [m + n for m, n in zip((mapX, mapY), viewRect)]
# }}}
# {{{ __del__(self): destructor method
def __del__(self): def __del__(self):
if self.canvasBitmap != None: if self.canvasBitmap != None:
self.canvasBitmap.Destroy(); self.canvasBitmap = None; self.canvasBitmap.Destroy(); self.canvasBitmap = None;
self._finiBrushesAndPens() self._finiBrushesAndPens()
# }}}
# #
# __init__(self, canvasSize, cellSize, fontName="Dejavu Sans Mono", fontPathName=os.path.join("assets", "fonts", "DejaVuSansMono.ttf")): initialisation method # __init__(self, canvasSize, cellSize, fontName="Dejavu Sans Mono", fontPathName=os.path.join("assets", "fonts", "DejaVuSansMono.ttf")): initialisation method

View File

@ -4,11 +4,10 @@
# Copyright (c) 2018, 2019 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de> # Copyright (c) 2018, 2019 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
# #
import os, sys, wx import os, sys, wx, wx.lib.agw.aui
# #
# Decorators # Decorators
# {{{ GuiCommandDecorator(targetObject)
def GuiCommandDecorator(caption, label, icon, accel, initialState): def GuiCommandDecorator(caption, label, icon, accel, initialState):
def GuiCommandDecoratorOuter(targetObject): def GuiCommandDecoratorOuter(targetObject):
if callable(targetObject): if callable(targetObject):
@ -17,8 +16,7 @@ def GuiCommandDecorator(caption, label, icon, accel, initialState):
targetObject.attrDict = {"caption": caption, "label": label, "icon": icon, "accel": accel, "initialState": initialState, "id": None} targetObject.attrDict = {"caption": caption, "label": label, "icon": icon, "accel": accel, "initialState": initialState, "id": None}
return targetObject return targetObject
return GuiCommandDecoratorOuter return GuiCommandDecoratorOuter
# }}}
# {{{ GuiCommandListDecorator(targetObject)
def GuiCommandListDecorator(idx, caption, label, icon, accel, initialState): def GuiCommandListDecorator(idx, caption, label, icon, accel, initialState):
def GuiCommandListDecoratorOuter(targetObject): def GuiCommandListDecoratorOuter(targetObject):
if callable(targetObject): if callable(targetObject):
@ -27,8 +25,7 @@ def GuiCommandListDecorator(idx, caption, label, icon, accel, initialState):
targetObject.attrList.insert(0, {"caption": caption, "label": label, "icon": icon, "accel": accel, "initialState": initialState, "id": None, "idx": idx}) targetObject.attrList.insert(0, {"caption": caption, "label": label, "icon": icon, "accel": accel, "initialState": initialState, "id": None, "idx": idx})
return targetObject return targetObject
return GuiCommandListDecoratorOuter return GuiCommandListDecoratorOuter
# }}}
# {{{ GuiSelectDecorator(targetObject)
def GuiSelectDecorator(idx, caption, label, icon, accel, initialState): def GuiSelectDecorator(idx, caption, label, icon, accel, initialState):
def GuiSelectDecoratorOuter(targetObject): def GuiSelectDecoratorOuter(targetObject):
if callable(targetObject): if callable(targetObject):
@ -38,8 +35,7 @@ def GuiSelectDecorator(idx, caption, label, icon, accel, initialState):
targetObject.attrList.insert(0, {"caption": caption, "label": label, "icon": icon, "accel": accel, "initialState": initialState, "id": None, "idx": idx}) targetObject.attrList.insert(0, {"caption": caption, "label": label, "icon": icon, "accel": accel, "initialState": initialState, "id": None, "idx": idx})
return targetObject return targetObject
return GuiSelectDecoratorOuter return GuiSelectDecoratorOuter
# }}}
# {{{ GuiSubMenuDecorator(targetObject)
def GuiSubMenuDecorator(caption, label, icon, accel, initialState): def GuiSubMenuDecorator(caption, label, icon, accel, initialState):
def GuiSubMenuDecoratorOuter(targetObject): def GuiSubMenuDecoratorOuter(targetObject):
if callable(targetObject): if callable(targetObject):
@ -49,7 +45,19 @@ def GuiSubMenuDecorator(caption, label, icon, accel, initialState):
targetObject.attrDict = {"caption": caption, "label": label, "icon": icon, "accel": accel, "initialState": initialState, "id": None, "menu":None} targetObject.attrDict = {"caption": caption, "label": label, "icon": icon, "accel": accel, "initialState": initialState, "id": None, "menu":None}
return targetObject return targetObject
return GuiSubMenuDecoratorOuter return GuiSubMenuDecoratorOuter
# }}}
class GuiToolBarArtProvider(wx.lib.agw.aui.AuiDefaultToolBarArt):
def DrawBackground(self, dc, wnd, _rect, horizontal=True):
dc.SetBrush(wx.Brush(wx.Colour(240, 240, 240, 0), wx.BRUSHSTYLE_SOLID)); dc.SetPen(wx.Pen(wx.Colour(240, 240, 240, 0), 1));
dc.DrawRectangle(*_rect)
dc.SetPen(wx.Pen(wx.Colour(180, 180, 180, 0), 1))
dc.DrawLine(0, _rect[3]-1, _rect[2], _rect[3]-1); dc.DrawLine(_rect[2]-1, 0, _rect[2]-1, _rect[3]-1);
dc.SetPen(wx.Pen(wx.Colour(255, 255, 255, 0), 1))
dc.DrawLine(0, 0, _rect[2]-1, 0); dc.DrawLine(0, 0, 0, _rect[3]-1);
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# #
# Non-items (0xf000-0xffff) # Non-items (0xf000-0xffff)
@ -57,13 +65,11 @@ NID_MENU_SEP = 0xf000
NID_TOOLBAR_HSEP = 0xf001 NID_TOOLBAR_HSEP = 0xf001
class GuiFrame(wx.Frame): class GuiFrame(wx.Frame):
# {{{ _initIcon(self, iconPathName)
def _initIcon(self, iconPathName): def _initIcon(self, iconPathName):
icon = wx.Icon() icon = wx.Icon()
icon.CopyFromBitmap(wx.Bitmap(iconPathName, wx.BITMAP_TYPE_ANY)) icon.CopyFromBitmap(wx.Bitmap(iconPathName, wx.BITMAP_TYPE_ANY))
self.SetIcon(icon) self.SetIcon(icon)
# }}}
# {{{ _initMenu(self, menuItem, menuWindow)
def _initMenu(self, menuItem, menuWindow): def _initMenu(self, menuItem, menuWindow):
if menuItem == NID_MENU_SEP: if menuItem == NID_MENU_SEP:
menuWindow.AppendSeparator() menuWindow.AppendSeparator()
@ -87,10 +93,9 @@ class GuiFrame(wx.Frame):
menuItemWindow.Check(menuItem.attrDict["initialState"]) menuItemWindow.Check(menuItem.attrDict["initialState"])
else: else:
menuItemWindow.Enable(menuItem.attrDict["initialState"]) menuItemWindow.Enable(menuItem.attrDict["initialState"])
# }}}
# {{{ loadAccels(self, menus, toolBars)
def loadAccels(self, menus, toolBars): def loadAccels(self, accelsIn, menus, toolBars):
def loadAccels_(accels): def loadAccels_(accels):
nonlocal accelTableEntries nonlocal accelTableEntries
accels_ = [] accels_ = []
@ -110,10 +115,9 @@ class GuiFrame(wx.Frame):
self.itemsById[accel.attrDict["id"]] = accel self.itemsById[accel.attrDict["id"]] = accel
self.Bind(wx.EVT_MENU, self.onMenu, id=accel.attrDict["id"]) self.Bind(wx.EVT_MENU, self.onMenu, id=accel.attrDict["id"])
accelTableEntries = [] accelTableEntries = []
[loadAccels_(menu[1:]) for menu in menus]; [loadAccels_(toolBar) for toolBar in toolBars]; [loadAccels_(accel) for accel in accelsIn]; [loadAccels_(menu[1:]) for menu in menus]; [loadAccels_(toolBar) for toolBar in toolBars];
self.SetAcceleratorTable(wx.AcceleratorTable(accelTableEntries)) self.SetAcceleratorTable(wx.AcceleratorTable(accelTableEntries))
# }}}
# {{{ loadBitmap(self, basePathName, descr, size=(16, 16))
def loadBitmap(self, basePathName, descr, size=(16, 16)): def loadBitmap(self, basePathName, descr, size=(16, 16)):
if descr == None: if descr == None:
descr = ["", None, wx.ArtProvider.GetBitmap(wx.ART_HELP, wx.ART_TOOLBAR, size)] descr = ["", None, wx.ArtProvider.GetBitmap(wx.ART_HELP, wx.ART_TOOLBAR, size)]
@ -126,8 +130,7 @@ class GuiFrame(wx.Frame):
elif len(descr) == 3: elif len(descr) == 3:
descr = ("", None, descr[2]) descr = ("", None, descr[2])
return descr return descr
# }}}
# {{{ loadMenus(self, menus)
def loadMenus(self, menus): def loadMenus(self, menus):
self.menuBar = wx.MenuBar() self.menuBar = wx.MenuBar()
for menu in menus: for menu in menus:
@ -142,11 +145,11 @@ class GuiFrame(wx.Frame):
self._initMenu(menuItem, menuWindow) self._initMenu(menuItem, menuWindow)
self.menuBar.Append(menuWindow, menu[0]) self.menuBar.Append(menuWindow, menu[0])
self.SetMenuBar(self.menuBar) self.SetMenuBar(self.menuBar)
# }}}
# {{{ loadToolBars(self, toolBars)
def loadToolBars(self, toolBars): def loadToolBars(self, toolBars):
for toolBar in toolBars: for toolBar in toolBars:
self.toolBars.append(wx.ToolBar(self.panelSkin, -1, style=wx.TB_FLAT | wx.HORIZONTAL | wx.TB_NODIVIDER)) self.toolBars.append(wx.lib.agw.aui.AuiToolBar(self.panelSkin, -1))
self.toolBars[-1].SetArtProvider(GuiToolBarArtProvider())
self.toolBars[-1].SetToolBitmapSize((16, 16)) self.toolBars[-1].SetToolBitmapSize((16, 16))
for toolBarItem in toolBar: for toolBarItem in toolBar:
if toolBarItem == NID_TOOLBAR_HSEP: if toolBarItem == NID_TOOLBAR_HSEP:
@ -156,42 +159,40 @@ class GuiFrame(wx.Frame):
toolBarItem.attrDict["id"] = wx.NewId() toolBarItem.attrDict["id"] = wx.NewId()
self.itemsById[toolBarItem.attrDict["id"]] = toolBarItem self.itemsById[toolBarItem.attrDict["id"]] = toolBarItem
if hasattr(toolBarItem, "isSelect"): if hasattr(toolBarItem, "isSelect"):
toolBarItemWindow = self.toolBars[-1].AddRadioTool(toolBarItem.attrDict["id"], toolBarItem.attrDict["caption"], toolBarItem.attrDict["icon"][2], shortHelp=toolBarItem.attrDict["label"]) toolBarItemWindow = self.toolBars[-1].AddRadioTool(toolBarItem.attrDict["id"], toolBarItem.attrDict["caption"], toolBarItem.attrDict["icon"][2], wx.NullBitmap, short_help_string=toolBarItem.attrDict["caption"])
else: else:
toolBarItemWindow = self.toolBars[-1].AddTool(toolBarItem.attrDict["id"], toolBarItem.attrDict["caption"], toolBarItem.attrDict["icon"][2], shortHelp=toolBarItem.attrDict["label"]) toolBarItemWindow = self.toolBars[-1].AddTool(toolBarItem.attrDict["id"], toolBarItem.attrDict["caption"], toolBarItem.attrDict["icon"][2], wx.NullBitmap, wx.ITEM_NORMAL, short_help_string=toolBarItem.attrDict["caption"])
self.toolBarItemsById[toolBarItem.attrDict["id"]] = toolBarItemWindow self.toolBarItemsById[toolBarItem.attrDict["id"]] = (self.toolBars[-1], toolBarItemWindow,)
self.Bind(wx.EVT_TOOL, self.onMenu, toolBarItemWindow) self.Bind(wx.EVT_TOOL, self.onMenu, toolBarItemWindow)
self.Bind(wx.EVT_TOOL_RCLICKED, self.onMenu, toolBarItemWindow) self.Bind(wx.EVT_TOOL_RCLICKED, self.onMenu, toolBarItemWindow)
if toolBarItem.attrDict["initialState"] != None: if toolBarItem.attrDict["initialState"] != None:
if hasattr(toolBarItem, "isSelect"): if hasattr(toolBarItem, "isSelect"):
toolBarItemWindow.Toggle(toolBarItem.attrDict["initialState"]) if toolBarItem.attrDict["initialState"]:
self.toolBars[-1].ToggleTool(toolBarItemWindow, True)
else: else:
toolBarItemWindow.Enable(toolBarItem.attrDict["initialState"]) self.toolBars[-1].EnableTool(toolBarItem.attrDict["id"], toolBarItem.attrDict["initialState"])
self.toolBars[-1].Refresh()
for toolBar in self.toolBars: for toolBar in self.toolBars:
self.sizerSkin.Add(toolBar, 0, wx.ALIGN_LEFT | wx.ALL, 3) self.sizerSkin.Add(toolBar, 0, wx.ALIGN_LEFT | wx.ALL, 3)
toolBar.Realize(); toolBar.Fit(); toolBar.Realize(); toolBar.Fit();
# }}}
# {{{ addWindow(self, window, border=14, expand=False)
def addWindow(self, window, border=14, expand=False): def addWindow(self, window, border=14, expand=False):
flags = wx.ALL; flags = flags | wx.EXPAND if expand else flags; flags = wx.ALL; flags = flags | wx.EXPAND if expand else flags;
self.sizerSkin.Add(window, 0, flags, border); self.sizerSkin.Fit(self.panelSkin); self.sizerSkin.Add(window, 0, flags, border); self.sizerSkin.Fit(self.panelSkin);
# }}}
# {{{ onChar(self, event)
def onChar(self, event): def onChar(self, event):
event.Skip() event.Skip()
# }}}
# {{{ onMenu(self, event)
def onMenu(self, event): def onMenu(self, event):
eventId = event.GetId() eventId = event.GetId()
if eventId in self.itemsById: if eventId in self.itemsById:
self.itemsById[eventId](event) self.itemsById[eventId](event)
else: else:
event.Skip() event.Skip()
# }}}
# {{{ onMouseWheel(self, event)
def onMouseWheel(self, event): def onMouseWheel(self, event):
event.Skip() event.Skip()
# }}}
# #
# __init__(self, iconPathName, size, parent=None, title=""): initialisation method # __init__(self, iconPathName, size, parent=None, title=""): initialisation method

View File

@ -7,7 +7,6 @@
import wx import wx
class GuiWindow(wx.ScrolledWindow): class GuiWindow(wx.ScrolledWindow):
# {{{ _updateScrollBars(self)
def _updateScrollBars(self): def _updateScrollBars(self):
if self.size != None: if self.size != None:
clientSize = self.GetClientSize() clientSize = self.GetClientSize()
@ -16,48 +15,39 @@ class GuiWindow(wx.ScrolledWindow):
elif self.scrollFlag \ elif self.scrollFlag \
and ((self.size[0] <= clientSize[0]) or (self.size[1] <= clientSize[1])): and ((self.size[0] <= clientSize[0]) or (self.size[1] <= clientSize[1])):
self.scrollFlag = False; super().SetVirtualSize((0, 0)); self.scrollFlag = False; super().SetVirtualSize((0, 0));
# }}}
# {{{ onClose(self, event)
def onClose(self, event): def onClose(self, event):
self.Destroy() self.Destroy()
# }}}
# {{{ onEnterWindow(self, event)
def onEnterWindow(self, event): def onEnterWindow(self, event):
event.Skip() event.Skip()
# }}}
# {{{ onKeyboardInput(self, event)
def onKeyboardInput(self, event): def onKeyboardInput(self, event):
return False return False
# }}}
# {{{ onLeaveWindow(self, event)
def onLeaveWindow(self, event): def onLeaveWindow(self, event):
event.Skip() event.Skip()
# }}}
# {{{ onMouseInput(self, event)
def onMouseInput(self, event): def onMouseInput(self, event):
return False return False
# }}}
# {{{ onPaint(self, event)
def onPaint(self, event): def onPaint(self, event):
event.Skip() event.Skip()
# }}}
# {{{ onScroll(self, event)
def onScroll(self, event): def onScroll(self, event):
event.Skip() event.Skip()
# }}}
# {{{ onSize(self, event)
def onSize(self, event): def onSize(self, event):
self._updateScrollBars(); event.Skip(); self._updateScrollBars(); event.Skip();
# }}}
# {{{ resize(self, newSize)
def resize(self, newSize): def resize(self, newSize):
self.size = newSize; self._updateScrollBars(); self.size = newSize; self._updateScrollBars();
self.SetMinSize(self.size); self.SetSize(wx.DefaultCoord, wx.DefaultCoord, *self.size); self.SetMinSize(self.size); self.SetSize(wx.DefaultCoord, wx.DefaultCoord, *self.size);
curWindow = self curWindow = self
while curWindow != None: while curWindow != None:
curWindow.Layout(); curWindow = curWindow.GetParent(); curWindow.Layout(); curWindow = curWindow.GetParent();
# }}}
# #
# __init__(self, parent, pos, scrollStep, style=0): initialisation method # __init__(self, parent, pos, scrollStep, style=0): initialisation method

View File

@ -10,12 +10,10 @@ from GuiWindow import GuiWindow
import json, os, sys, wx import json, os, sys, wx
class RoarAssetsWindow(GuiMiniFrame): class RoarAssetsWindow(GuiMiniFrame):
# {{{ _drawPatch(self, canvas, eventDc, isCursor, patch)
def _drawPatch(self, canvas, eventDc, isCursor, patch): def _drawPatch(self, canvas, eventDc, isCursor, patch):
if not isCursor: if not isCursor:
self.backend.drawPatch(canvas, eventDc, patch) self.backend.drawPatch(canvas, eventDc, patch)
# }}}
# {{{ _import(self, f, pathName)
def _import(self, f, pathName): def _import(self, f, pathName):
rc = False rc = False
self.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) self.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
@ -28,8 +26,7 @@ class RoarAssetsWindow(GuiMiniFrame):
rc, error, newMap, newPathName, newSize = False, str(e), None, None, None rc, error, newMap, newPathName, newSize = False, str(e), None, None, None
self.SetCursor(wx.Cursor(wx.NullCursor)) self.SetCursor(wx.Cursor(wx.NullCursor))
return rc, error, canvas, newMap, newPathName, newSize return rc, error, canvas, newMap, newPathName, newSize
# }}}
# {{{ _importFiles(self, f, wildcard)
def _importFiles(self, f, wildcard): def _importFiles(self, f, wildcard):
resultList = [] resultList = []
with wx.FileDialog(self, "Load...", os.getcwd(), "", wildcard, wx.FD_MULTIPLE | wx.FD_OPEN) as dialog: with wx.FileDialog(self, "Load...", os.getcwd(), "", wildcard, wx.FD_MULTIPLE | wx.FD_OPEN) as dialog:
@ -42,8 +39,7 @@ class RoarAssetsWindow(GuiMiniFrame):
resultList += [self._import(f, pathName)] resultList += [self._import(f, pathName)]
self.lastDir = os.path.dirname(pathName) self.lastDir = os.path.dirname(pathName)
return resultList return resultList
# }}}
# {{{ _load_list(self, pathName)
def _load_list(self, pathName): def _load_list(self, pathName):
try: try:
with open(pathName, "r") as fileObject: with open(pathName, "r") as fileObject:
@ -84,8 +80,7 @@ class RoarAssetsWindow(GuiMiniFrame):
self.SetCursor(wx.Cursor(wx.NullCursor)) self.SetCursor(wx.Cursor(wx.NullCursor))
with wx.MessageDialog(self, "Error: {}".format(str(e)), "", wx.OK | wx.OK_DEFAULT) as dialog: with wx.MessageDialog(self, "Error: {}".format(str(e)), "", wx.OK | wx.OK_DEFAULT) as dialog:
dialogChoice = dialog.ShowModal() dialogChoice = dialog.ShowModal()
# }}}
# {{{ _updateScrollBars(self)
def _updateScrollBars(self): def _updateScrollBars(self):
clientSize = self.panelCanvas.GetClientSize() clientSize = self.panelCanvas.GetClientSize()
if self.currentIndex != None: if self.currentIndex != None:
@ -99,9 +94,8 @@ class RoarAssetsWindow(GuiMiniFrame):
elif self.scrollFlag \ elif self.scrollFlag \
and ((panelSize[0] <= clientSize[0]) or (panelSize[1] <= clientSize[1])): and ((panelSize[0] <= clientSize[0]) or (panelSize[1] <= clientSize[1])):
self.scrollFlag = False; super(wx.ScrolledWindow, self.panelCanvas).SetVirtualSize((0, 0)); self.scrollFlag = False; super(wx.ScrolledWindow, self.panelCanvas).SetVirtualSize((0, 0));
# }}}
# {{{ drawCanvas(self, canvas)
def drawCanvas(self, canvas): def drawCanvas(self, canvas):
panelSize = [a * b for a, b in zip(canvas.size, self.cellSize)] panelSize = [a * b for a, b in zip(canvas.size, self.cellSize)]
self.panelCanvas.SetMinSize(panelSize); self.panelCanvas.SetSize(wx.DefaultCoord, wx.DefaultCoord, *panelSize); self.panelCanvas.SetMinSize(panelSize); self.panelCanvas.SetSize(wx.DefaultCoord, wx.DefaultCoord, *panelSize);
@ -115,12 +109,10 @@ class RoarAssetsWindow(GuiMiniFrame):
for numCol in range(canvas.size[0]): for numCol in range(canvas.size[0]):
self.backend.drawPatch(canvas, eventDc, [numCol, numRow, *canvas.map[numRow][numCol]]) self.backend.drawPatch(canvas, eventDc, [numCol, numRow, *canvas.map[numRow][numCol]])
eventDc.SetDeviceOrigin(*eventDcOrigin) eventDc.SetDeviceOrigin(*eventDcOrigin)
# }}}
# {{{ onPaint(self, event)
def onPaint(self, event): def onPaint(self, event):
self.backend.onPaint(self.panelCanvas.GetClientSize(), self.panelCanvas, self.panelCanvas.GetViewStart()) self.backend.onPaint(self.panelCanvas.GetClientSize(), self.panelCanvas, self.panelCanvas.GetViewStart())
# }}}
# {{{ onPanelLeftDown(self, event)
def onPanelLeftDown(self, event): def onPanelLeftDown(self, event):
self.panelCanvas.SetFocus() self.panelCanvas.SetFocus()
if (self.currentIndex != None): if (self.currentIndex != None):
@ -130,16 +122,13 @@ class RoarAssetsWindow(GuiMiniFrame):
dropSource.SetData(textDataObject) dropSource.SetData(textDataObject)
result = dropSource.DoDragDrop(True) result = dropSource.DoDragDrop(True)
event.Skip() event.Skip()
# }}}
# {{{ onPanelPaint(self, event)
def onPanelPaint(self, event): def onPanelPaint(self, event):
self.backend.onPaint(self.panelCanvas.GetClientSize(), self.panelCanvas, self.panelCanvas.GetViewStart()) self.backend.onPaint(self.panelCanvas.GetClientSize(), self.panelCanvas, self.panelCanvas.GetViewStart())
# }}}
# {{{ onPanelSize(self, event)
def onPanelSize(self, event): def onPanelSize(self, event):
self._updateScrollBars(); event.Skip(); self._updateScrollBars(); event.Skip();
# }}}
# {{{ resize(self, canvas, newSize)
def resize(self, canvas, newSize): def resize(self, canvas, newSize):
oldSize = [0, 0] if canvas.map == None else canvas.size oldSize = [0, 0] if canvas.map == None else canvas.size
deltaSize = [b - a for a, b in zip(oldSize, newSize)] deltaSize = [b - a for a, b in zip(oldSize, newSize)]
@ -161,8 +150,7 @@ class RoarAssetsWindow(GuiMiniFrame):
for numNewCol in range(newSize[0]): for numNewCol in range(newSize[0]):
self._drawPatch(canvas, eventDc, False, [numNewCol, numNewRow, 1, 1, 0, " "]) self._drawPatch(canvas, eventDc, False, [numNewCol, numNewRow, 1, 1, 0, " "])
eventDc.SetDeviceOrigin(*eventDcOrigin) eventDc.SetDeviceOrigin(*eventDcOrigin)
# }}}
# {{{ update(self, canvas, newSize, newCanvas=None)
def update(self, canvas, newSize, newCanvas=None): def update(self, canvas, newSize, newCanvas=None):
self.resize(canvas, newSize); self.resize(canvas, newSize);
canvas.update(newSize, newCanvas); canvas.update(newSize, newCanvas);
@ -172,21 +160,17 @@ class RoarAssetsWindow(GuiMiniFrame):
for numCol in range(canvas.size[0]): for numCol in range(canvas.size[0]):
self.backend.drawPatch(canvas, eventDc, [numCol, numRow, *canvas.map[numRow][numCol]]) self.backend.drawPatch(canvas, eventDc, [numCol, numRow, *canvas.map[numRow][numCol]])
eventDc.SetDeviceOrigin(*eventDcOrigin) eventDc.SetDeviceOrigin(*eventDcOrigin)
# }}}
# {{{ onImportAnsi(self, event)
def onImportAnsi(self, event): def onImportAnsi(self, event):
event.Skip() event.Skip()
# }}}
# {{{ onImportFromClipboard(self, event)
def onImportFromClipboard(self, event): def onImportFromClipboard(self, event):
event.Skip() event.Skip()
# }}}
# {{{ onImportSauce(self, event)
def onImportSauce(self, event): def onImportSauce(self, event):
event.Skip() event.Skip()
# }}}
# {{{ onChar(self, event)
def onChar(self, event): def onChar(self, event):
if (event.GetModifiers() == wx.MOD_NONE) \ if (event.GetModifiers() == wx.MOD_NONE) \
and (event.GetKeyCode() in (wx.WXK_DOWN, wx.WXK_UP)): and (event.GetKeyCode() in (wx.WXK_DOWN, wx.WXK_UP)):
@ -194,8 +178,7 @@ class RoarAssetsWindow(GuiMiniFrame):
return wx.PostEvent(self.listView, event) return wx.PostEvent(self.listView, event)
else: else:
event.Skip() event.Skip()
# }}}
# {{{ onListViewChar(self, event)
def onListViewChar(self, event): def onListViewChar(self, event):
index, rc = self.listView.GetFirstSelected(), False index, rc = self.listView.GetFirstSelected(), False
if index != -1: if index != -1:
@ -204,14 +187,12 @@ class RoarAssetsWindow(GuiMiniFrame):
self.currentIndex, rc = index, True; self.onRemove(None); self.currentIndex, rc = index, True; self.onRemove(None);
if not rc: if not rc:
event.Skip() event.Skip()
# }}}
# {{{ onListViewItemSelected(self, event)
def onListViewItemSelected(self, event): def onListViewItemSelected(self, event):
self.currentIndex = event.GetItem().GetId() self.currentIndex = event.GetItem().GetId()
item = [self.listView.GetItem(self.currentIndex, col).GetText() for col in (0, 1)] item = [self.listView.GetItem(self.currentIndex, col).GetText() for col in (0, 1)]
self.drawCanvas(self.canvasList[self.currentIndex][0]) self.drawCanvas(self.canvasList[self.currentIndex][0])
# }}}
# {{{ onListViewRightDown(self, event)
def onListViewRightDown(self, event): def onListViewRightDown(self, event):
eventPoint = event.GetPosition() eventPoint = event.GetPosition()
if self.currentIndex == None: if self.currentIndex == None:
@ -223,8 +204,7 @@ class RoarAssetsWindow(GuiMiniFrame):
else: else:
self.contextMenuItems[4].Enable(True) self.contextMenuItems[4].Enable(True)
self.PopupMenu(self.contextMenu, eventPoint) self.PopupMenu(self.contextMenu, eventPoint)
# }}}
# {{{ onLoad(self, event)
def onLoad(self, event): def onLoad(self, event):
def importmIRC(canvas, pathName): def importmIRC(canvas, pathName):
rc, error = canvas.importStore.importTextFile(pathName) rc, error = canvas.importStore.importTextFile(pathName)
@ -250,7 +230,7 @@ class RoarAssetsWindow(GuiMiniFrame):
dialogChoice = dialog.ShowModal() dialogChoice = dialog.ShowModal()
if dialogChoice == wx.ID_CANCEL: if dialogChoice == wx.ID_CANCEL:
break break
# }}}
# {{{ onLoadList(self, event) # {{{ onLoadList(self, event)
def onLoadList(self, event): def onLoadList(self, event):
rc = True rc = True
@ -260,8 +240,7 @@ class RoarAssetsWindow(GuiMiniFrame):
if dialog.ShowModal() != wx.ID_CANCEL: if dialog.ShowModal() != wx.ID_CANCEL:
pathName = dialog.GetPath(); self.lastDir = os.path.dirname(pathName); pathName = dialog.GetPath(); self.lastDir = os.path.dirname(pathName);
self._load_list(pathName) self._load_list(pathName)
# }}}
# {{{ onRemove(self, event)
def onRemove(self, event): def onRemove(self, event):
del self.canvasList[self.currentIndex]; self.listView.DeleteItem(self.currentIndex); del self.canvasList[self.currentIndex]; self.listView.DeleteItem(self.currentIndex);
itemCount = self.listView.GetItemCount() itemCount = self.listView.GetItemCount()
@ -280,8 +259,7 @@ class RoarAssetsWindow(GuiMiniFrame):
self.currentIndex = None self.currentIndex = None
[self.listView.SetColumnWidth(col, wx.LIST_AUTOSIZE_USEHEADER) for col in (0, 1)] [self.listView.SetColumnWidth(col, wx.LIST_AUTOSIZE_USEHEADER) for col in (0, 1)]
self.drawCanvas(Canvas((0, 0))) self.drawCanvas(Canvas((0, 0)))
# }}}
# {{{ onSaveList(self, event)
def onSaveList(self, event): def onSaveList(self, event):
rc = True rc = True
if len(self.canvasList): if len(self.canvasList):
@ -299,7 +277,7 @@ class RoarAssetsWindow(GuiMiniFrame):
if not rc: if not rc:
with wx.MessageDialog(self, "Error: {}".format(error), "", wx.OK | wx.OK_DEFAULT) as dialog: with wx.MessageDialog(self, "Error: {}".format(error), "", wx.OK | wx.OK_DEFAULT) as dialog:
dialogChoice = dialog.ShowModal() dialogChoice = dialog.ShowModal()
# }}}
# #
# __init__(self, backend, cellSize, parent, pos=None, size=(400, 400), title="Assets"): initialisation method # __init__(self, backend, cellSize, parent, pos=None, size=(400, 400), title="Assets"): initialisation method

View File

@ -14,32 +14,33 @@ from RoarCanvasCommandsTools import RoarCanvasCommandsTools
import os, wx import os, wx
class RoarCanvasCommands(RoarCanvasCommandsFile, RoarCanvasCommandsEdit, RoarCanvasCommandsTools, RoarCanvasCommandsOperators, RoarCanvasCommandsHelp): class RoarCanvasCommands(RoarCanvasCommandsFile, RoarCanvasCommandsEdit, RoarCanvasCommandsTools, RoarCanvasCommandsOperators, RoarCanvasCommandsHelp):
# {{{ _initColourBitmaps(self)
def _initColourBitmaps(self): def _initColourBitmaps(self):
for numColour in range(len(RoarCanvasCommandsEdit.canvasColour.attrList)): def _initColourBitmaps_(cmd, cmdAlpha, div):
if numColour < len(Colours): for numColour in range(len(cmd.attrList)):
toolBitmapColour = Colours[numColour][0:4] if numColour < len(Colours):
toolBitmap = wx.Bitmap((16, 16)) toolBitmapColour = Colours[numColour][0:4]
toolBitmapDc = wx.MemoryDC(); toolBitmapDc.SelectObject(toolBitmap); toolBitmap = wx.Bitmap((16, 16))
toolBitmapBrush = wx.Brush(wx.Colour(toolBitmapColour), wx.BRUSHSTYLE_SOLID) toolBitmapDc = wx.MemoryDC(); toolBitmapDc.SelectObject(toolBitmap);
toolBitmapDc.SetBrush(toolBitmapBrush) toolBitmapBrush = wx.Brush(wx.Colour([*[int(c / div) for c in toolBitmapColour[:3]], 255]), wx.BRUSHSTYLE_SOLID)
toolBitmapDc.SetBackground(toolBitmapBrush) toolBitmapDc.SetBrush(toolBitmapBrush)
toolBitmapDc.SetPen(wx.Pen(wx.Colour(toolBitmapColour), 1)) toolBitmapDc.SetBackground(toolBitmapBrush)
toolBitmapDc.DrawRectangle(0, 0, 16, 16) toolBitmapDc.SetPen(wx.Pen(wx.Colour(toolBitmapColour), 1))
RoarCanvasCommandsEdit.canvasColour.attrList[numColour]["icon"] = ["", None, toolBitmap] toolBitmapDc.DrawRectangle(0, 0, 16, 16)
toolBitmapColours = ((0, 0, 0, 255), (255, 255, 255, 255)) cmd.attrList[numColour]["icon"] = ["", None, toolBitmap]
toolBitmap = wx.Bitmap((16, 16)) toolBitmapColours = ((0, 0, 0, 255), (255, 255, 255, 255))
toolBitmapDc = wx.MemoryDC(); toolBitmapDc.SelectObject(toolBitmap); toolBitmap = wx.Bitmap((16, 16))
toolBitmapBrush = [wx.Brush(wx.Colour(c), wx.BRUSHSTYLE_SOLID) for c in toolBitmapColours] toolBitmapDc = wx.MemoryDC(); toolBitmapDc.SelectObject(toolBitmap);
toolBitmapDc.SetBrush(toolBitmapBrush[1]) toolBitmapBrush = [wx.Brush(wx.Colour(c), wx.BRUSHSTYLE_SOLID) for c in toolBitmapColours]
toolBitmapDc.SetBackground(toolBitmapBrush[1]) toolBitmapDc.SetBrush(toolBitmapBrush[1])
toolBitmapDc.SetPen(wx.Pen(wx.Colour(toolBitmapColours[1]), 1)) toolBitmapDc.SetBackground(toolBitmapBrush[1])
toolBitmapDc.DrawRectangle(0, 0, 8, 8) toolBitmapDc.SetPen(wx.Pen(wx.Colour(toolBitmapColours[1]), 1))
toolBitmapDc.DrawRectangle(8, 8, 16, 16) toolBitmapDc.DrawRectangle(0, 0, 8, 8)
RoarCanvasCommandsEdit.canvasColourAlpha.attrList[0]["icon"] = ["", None, toolBitmap] toolBitmapDc.DrawRectangle(8, 8, 16, 16)
# }}} cmdAlpha.attrList[0]["icon"] = ["", None, toolBitmap]
_initColourBitmaps_(RoarCanvasCommandsEdit.canvasColour, RoarCanvasCommandsEdit.canvasColourAlpha, 1.0)
_initColourBitmaps_(RoarCanvasCommandsEdit.canvasColourBackground, RoarCanvasCommandsEdit.canvasColourAlphaBackground, 0.5)
# {{{ update(self, **kwargs)
def update(self, **kwargs): def update(self, **kwargs):
self.lastPanelState.update(kwargs); textItems = []; self.lastPanelState.update(kwargs); textItems = [];
if "cellPos" in self.lastPanelState: if "cellPos" in self.lastPanelState:
@ -53,8 +54,20 @@ class RoarCanvasCommands(RoarCanvasCommandsFile, RoarCanvasCommandsEdit, RoarCan
textItems.append("{} on {}".format( textItems.append("{} on {}".format(
Colours[self.lastPanelState["colours"][0]][4] if self.lastPanelState["colours"][0] != -1 else "Transparent", Colours[self.lastPanelState["colours"][0]][4] if self.lastPanelState["colours"][0] != -1 else "Transparent",
Colours[self.lastPanelState["colours"][1]][4] if self.lastPanelState["colours"][1] != -1 else "Transparent")) Colours[self.lastPanelState["colours"][1]][4] if self.lastPanelState["colours"][1] != -1 else "Transparent"))
toolBar = self.parentFrame.toolBarItemsById[self.canvasColour(self.canvasColour, self.lastPanelState["colours"][0]).attrDict["id"]].GetToolBar() toolBar = self.parentFrame.toolBarItemsById[self.canvasColour(self.canvasColour, self.lastPanelState["colours"][0]).attrDict["id"]][0]
toolBar.ToggleTool(self.canvasColour(self.canvasColour, self.lastPanelState["colours"][0]).attrDict["id"], True) toolBarBg = self.parentFrame.toolBarItemsById[self.canvasColourBackground(self.canvasColourBackground, self.lastPanelState["colours"][1]).attrDict["id"]][0]
if self.lastPanelState["colours"][0] != -1:
toolBar.ToggleTool(self.canvasColour(self.canvasColour, self.lastPanelState["colours"][0]).attrDict["id"], True)
toolBar.Refresh()
else:
toolBar.ToggleTool(self.canvasColourAlpha(self.canvasColourAlpha, 0).attrDict["id"], True)
toolBar.Refresh()
if self.lastPanelState["colours"][1] != -1:
toolBarBg.ToggleTool(self.canvasColourBackground(self.canvasColourBackground, self.lastPanelState["colours"][1]).attrDict["id"], True)
toolBarBg.Refresh()
else:
toolBarBg.ToggleTool(self.canvasColourAlphaBackground(self.canvasColourAlphaBackground, 0).attrDict["id"], True)
toolBarBg.Refresh()
if "pathName" in self.lastPanelState: if "pathName" in self.lastPanelState:
if self.lastPanelState["pathName"] != None: if self.lastPanelState["pathName"] != None:
basePathName = os.path.basename(self.lastPanelState["pathName"]) basePathName = os.path.basename(self.lastPanelState["pathName"])
@ -75,35 +88,37 @@ class RoarCanvasCommands(RoarCanvasCommandsFile, RoarCanvasCommandsEdit, RoarCan
and (self.lastPanelState["undoInhibit"]): and (self.lastPanelState["undoInhibit"]):
for item in (self.canvasRedo, self.canvasUndo): for item in (self.canvasRedo, self.canvasUndo):
self.parentFrame.menuItemsById[item.attrDict["id"]].Enable(False) self.parentFrame.menuItemsById[item.attrDict["id"]].Enable(False)
toolBar = self.parentFrame.toolBarItemsById[item.attrDict["id"]].GetToolBar() toolBar = self.parentFrame.toolBarItemsById[item.attrDict["id"]][0]
toolBar.EnableTool(item.attrDict["id"], False) toolBar.EnableTool(item.attrDict["id"], False); toolBar.Refresh();
elif "undoLevel" in self.lastPanelState: elif "undoLevel" in self.lastPanelState:
if (self.lastPanelState["undoLevel"] >= 0) \ if (self.lastPanelState["undoLevel"] >= 0) \
and (self.lastPanelState["undoLevel"] < (len(self.parentCanvas.canvas.journal.patchesUndo) - 1)): and (self.lastPanelState["undoLevel"] < (len(self.parentCanvas.canvas.journal.patchesUndo) - 1)):
self.parentFrame.menuItemsById[self.canvasUndo.attrDict["id"]].Enable(True) self.parentFrame.menuItemsById[self.canvasUndo.attrDict["id"]].Enable(True)
toolBar = self.parentFrame.toolBarItemsById[self.canvasUndo.attrDict["id"]].GetToolBar() toolBar = self.parentFrame.toolBarItemsById[self.canvasUndo.attrDict["id"]][0]
toolBar.EnableTool(self.canvasUndo.attrDict["id"], True) toolBar.EnableTool(self.canvasUndo.attrDict["id"], True); toolBar.Refresh();
else: else:
self.parentFrame.menuItemsById[self.canvasUndo.attrDict["id"]].Enable(False) self.parentFrame.menuItemsById[self.canvasUndo.attrDict["id"]].Enable(False)
toolBar = self.parentFrame.toolBarItemsById[self.canvasUndo.attrDict["id"]].GetToolBar() toolBar = self.parentFrame.toolBarItemsById[self.canvasUndo.attrDict["id"]][0]
toolBar.EnableTool(self.canvasUndo.attrDict["id"], False) toolBar.EnableTool(self.canvasUndo.attrDict["id"], False); toolBar.Refresh();
if self.lastPanelState["undoLevel"] > 0: if self.lastPanelState["undoLevel"] > 0:
self.parentFrame.menuItemsById[self.canvasRedo.attrDict["id"]].Enable(True) self.parentFrame.menuItemsById[self.canvasRedo.attrDict["id"]].Enable(True)
toolBar = self.parentFrame.toolBarItemsById[self.canvasRedo.attrDict["id"]].GetToolBar() toolBar = self.parentFrame.toolBarItemsById[self.canvasRedo.attrDict["id"]][0]
toolBar.EnableTool(self.canvasRedo.attrDict["id"], True) toolBar.EnableTool(self.canvasRedo.attrDict["id"], True); toolBar.Refresh();
else: else:
self.parentFrame.menuItemsById[self.canvasRedo.attrDict["id"]].Enable(False) self.parentFrame.menuItemsById[self.canvasRedo.attrDict["id"]].Enable(False)
toolBar = self.parentFrame.toolBarItemsById[self.canvasRedo.attrDict["id"]].GetToolBar() toolBar = self.parentFrame.toolBarItemsById[self.canvasRedo.attrDict["id"]][0]
toolBar.EnableTool(self.canvasRedo.attrDict["id"], False) toolBar.EnableTool(self.canvasRedo.attrDict["id"], False); toolBar.Refresh();
# }}}
# #
# __init__(self, parentCanvas, parentFrame): # __init__(self, parentCanvas, parentFrame):
def __init__(self, parentCanvas, parentFrame): def __init__(self, parentCanvas, parentFrame):
menus, toolBars = [], [] accels, menus, toolBars = [], [], []
self.canvasPathName, self.lastPanelState, self.parentCanvas, self.parentFrame = None, {}, parentCanvas, parentFrame self.canvasPathName, self.lastPanelState, self.parentCanvas, self.parentFrame = None, {}, parentCanvas, parentFrame
for classObject in self.__class__.__bases__: for classObject in self.__class__.__bases__:
classObject.__init__(self) classObject.__init__(self)
if len(self.accels):
accels += self.accels
if len(self.menus): if len(self.menus):
menus += self.menus menus += self.menus
if len(self.toolBars): if len(self.toolBars):
@ -115,20 +130,27 @@ class RoarCanvasCommands(RoarCanvasCommandsFile, RoarCanvasCommandsEdit, RoarCan
[self.canvasNew, self.canvasOpen, self.canvasSave, self.canvasSaveAs, NID_TOOLBAR_HSEP, [self.canvasNew, self.canvasOpen, self.canvasSave, self.canvasSaveAs, NID_TOOLBAR_HSEP,
self.canvasUndo, self.canvasRedo, NID_TOOLBAR_HSEP, self.canvasUndo, self.canvasRedo, NID_TOOLBAR_HSEP,
self.canvasCut, self.canvasCopy, self.canvasPaste, self.canvasDelete, NID_TOOLBAR_HSEP, self.canvasCut, self.canvasCopy, self.canvasPaste, self.canvasDelete, NID_TOOLBAR_HSEP,
self.canvasCanvasSize(self.canvasCanvasSize, 1, True), self.canvasCanvasSize(self.canvasCanvasSize, 1, False), self.canvasCanvasSize(self.canvasCanvasSize, 0, True), self.canvasCanvasSize(self.canvasCanvasSize, 0, False), NID_TOOLBAR_HSEP, self.canvasAssetsWindowHide, self.canvasAssetsWindowShow, NID_TOOLBAR_HSEP,
self.canvasCanvasSize(self.canvasCanvasSize, 2, True), self.canvasCanvasSize(self.canvasCanvasSize, 2, False), NID_TOOLBAR_HSEP,
self.canvasTool(self.canvasTool, 1), self.canvasTool(self.canvasTool, 5), self.canvasTool(self.canvasTool, 0), self.canvasTool(self.canvasTool, 2), self.canvasTool(self.canvasTool, 3), self.canvasTool(self.canvasTool, 6), self.canvasTool(self.canvasTool, 4), self.canvasTool(self.canvasTool, 1), self.canvasTool(self.canvasTool, 5), self.canvasTool(self.canvasTool, 0), self.canvasTool(self.canvasTool, 2), self.canvasTool(self.canvasTool, 3), self.canvasTool(self.canvasTool, 6), self.canvasTool(self.canvasTool, 4),
]) ])
# XXX
toolBars.append( toolBars.append(
[self.canvasColour(self.canvasColour, 0), self.canvasColour(self.canvasColour, 1), self.canvasColour(self.canvasColour, 2), self.canvasColour(self.canvasColour, 3), [self.canvasColour(self.canvasColour, 0), self.canvasColour(self.canvasColour, 1), self.canvasColour(self.canvasColour, 2), self.canvasColour(self.canvasColour, 3),
self.canvasColour(self.canvasColour, 4), self.canvasColour(self.canvasColour, 5), self.canvasColour(self.canvasColour, 6), self.canvasColour(self.canvasColour, 7), self.canvasColour(self.canvasColour, 4), self.canvasColour(self.canvasColour, 5), self.canvasColour(self.canvasColour, 6), self.canvasColour(self.canvasColour, 7),
self.canvasColour(self.canvasColour, 8), self.canvasColour(self.canvasColour, 9), self.canvasColour(self.canvasColour, 10), self.canvasColour(self.canvasColour, 11), self.canvasColour(self.canvasColour, 8), self.canvasColour(self.canvasColour, 9), self.canvasColour(self.canvasColour, 10), self.canvasColour(self.canvasColour, 11),
self.canvasColour(self.canvasColour, 12), self.canvasColour(self.canvasColour, 13), self.canvasColour(self.canvasColour, 14), self.canvasColour(self.canvasColour, 15), self.canvasColour(self.canvasColour, 12), self.canvasColour(self.canvasColour, 13), self.canvasColour(self.canvasColour, 14), self.canvasColour(self.canvasColour, 15),
self.canvasColourAlpha(self.canvasColourAlpha, 0), NID_TOOLBAR_HSEP, self.canvasColourAlpha(self.canvasColourAlpha, 0), self.canvasColoursFlip, NID_TOOLBAR_HSEP,
self.canvasBrushSize(self.canvasBrushSize, 1, True), self.canvasBrushSize(self.canvasBrushSize, 0, False), self.canvasBrushSize(self.canvasBrushSize, 1, True), self.canvasBrushSize(self.canvasBrushSize, 1, False), NID_TOOLBAR_HSEP, self.canvasBrushSize(self.canvasBrushSize, 1, True), self.canvasBrushSize(self.canvasBrushSize, 0, False), self.canvasBrushSize(self.canvasBrushSize, 1, True), self.canvasBrushSize(self.canvasBrushSize, 1, False), NID_TOOLBAR_HSEP,
self.canvasBrushSize(self.canvasBrushSize, 2, True), self.canvasBrushSize(self.canvasBrushSize, 2, False), self.canvasBrushSize(self.canvasBrushSize, 2, True), self.canvasBrushSize(self.canvasBrushSize, 2, False),
]) ])
self.menus, self.toolBars = menus, toolBars toolBars.append(
[self.canvasColourBackground(self.canvasColourBackground, 0), self.canvasColourBackground(self.canvasColourBackground, 1), self.canvasColourBackground(self.canvasColourBackground, 2), self.canvasColourBackground(self.canvasColourBackground, 3),
self.canvasColourBackground(self.canvasColourBackground, 4), self.canvasColourBackground(self.canvasColourBackground, 5), self.canvasColourBackground(self.canvasColourBackground, 6), self.canvasColourBackground(self.canvasColourBackground, 7),
self.canvasColourBackground(self.canvasColourBackground, 8), self.canvasColourBackground(self.canvasColourBackground, 9), self.canvasColourBackground(self.canvasColourBackground, 10), self.canvasColourBackground(self.canvasColourBackground, 11),
self.canvasColourBackground(self.canvasColourBackground, 12), self.canvasColourBackground(self.canvasColourBackground, 13), self.canvasColourBackground(self.canvasColourBackground, 14), self.canvasColourBackground(self.canvasColourBackground, 15),
self.canvasColourAlphaBackground(self.canvasColourAlphaBackground, 0), self.canvasColoursFlip, NID_TOOLBAR_HSEP,
self.canvasCanvasSize(self.canvasCanvasSize, 1, True), self.canvasCanvasSize(self.canvasCanvasSize, 1, False), self.canvasCanvasSize(self.canvasCanvasSize, 0, True), self.canvasCanvasSize(self.canvasCanvasSize, 0, False), NID_TOOLBAR_HSEP,
self.canvasCanvasSize(self.canvasCanvasSize, 2, True), self.canvasCanvasSize(self.canvasCanvasSize, 2, False),
])
self.accels, self.menus, self.toolBars = accels, menus, toolBars
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=0 # vim:expandtab foldmethod=marker sw=4 ts=4 tw=0

View File

@ -8,21 +8,26 @@ from GuiFrame import GuiCommandDecorator, GuiCommandListDecorator, GuiSelectDeco
import wx import wx
class RoarCanvasCommandsEdit(): class RoarCanvasCommandsEdit():
# {{{ canvasAssetsWindowHide(self, event) @GuiCommandDecorator("Hide assets window", "Hide assets window", ["toolHideAssetsWindow.png"], None, False)
@GuiCommandDecorator("Hide assets window", "Hide assets window", None, None, False)
def canvasAssetsWindowHide(self, event): def canvasAssetsWindowHide(self, event):
self.parentFrame.assetsWindow.Show(False) self.parentFrame.assetsWindow.Show(False)
self.parentFrame.menuItemsById[self.canvasAssetsWindowHide.attrDict["id"]].Enable(False) self.parentFrame.menuItemsById[self.canvasAssetsWindowHide.attrDict["id"]].Enable(False)
self.parentFrame.menuItemsById[self.canvasAssetsWindowShow.attrDict["id"]].Enable(True) self.parentFrame.menuItemsById[self.canvasAssetsWindowShow.attrDict["id"]].Enable(True)
# }}} toolBar = self.parentFrame.toolBarItemsById[self.canvasAssetsWindowHide.attrDict["id"]][0]
# {{{ canvasAssetsWindowShow(self, event) toolBar.EnableTool(self.canvasAssetsWindowHide.attrDict["id"], False)
@GuiCommandDecorator("Show assets window", "Show assets window", None, None, False) toolBar.EnableTool(self.canvasAssetsWindowShow.attrDict["id"], True)
toolBar.Refresh()
@GuiCommandDecorator("Show assets window", "Show assets window", ["toolShowAssetsWindow.png"], None, False)
def canvasAssetsWindowShow(self, event): def canvasAssetsWindowShow(self, event):
self.parentFrame.assetsWindow.Show(True) self.parentFrame.assetsWindow.Show(True)
self.parentFrame.menuItemsById[self.canvasAssetsWindowHide.attrDict["id"]].Enable(True) self.parentFrame.menuItemsById[self.canvasAssetsWindowHide.attrDict["id"]].Enable(True)
self.parentFrame.menuItemsById[self.canvasAssetsWindowShow.attrDict["id"]].Enable(False) self.parentFrame.menuItemsById[self.canvasAssetsWindowShow.attrDict["id"]].Enable(False)
# }}} toolBar = self.parentFrame.toolBarItemsById[self.canvasAssetsWindowHide.attrDict["id"]][0]
# {{{ canvasBrush(self, f, idx) toolBar.EnableTool(self.canvasAssetsWindowHide.attrDict["id"], True)
toolBar.EnableTool(self.canvasAssetsWindowShow.attrDict["id"], False)
toolBar.Refresh()
@GuiSelectDecorator(0, "Solid brush", "Solid brush", None, None, True) @GuiSelectDecorator(0, "Solid brush", "Solid brush", None, None, True)
def canvasBrush(self, f, idx): def canvasBrush(self, f, idx):
def canvasBrush_(self, event): def canvasBrush_(self, event):
@ -30,14 +35,13 @@ class RoarCanvasCommandsEdit():
setattr(canvasBrush_, "attrDict", f.attrList[idx]) setattr(canvasBrush_, "attrDict", f.attrList[idx])
setattr(canvasBrush_, "isSelect", True) setattr(canvasBrush_, "isSelect", True)
return canvasBrush_ return canvasBrush_
# }}}
# {{{ canvasBrushSize(self, f, dimension, incrFlag)
@GuiCommandListDecorator(0, "Decrease brush width", "Decrease brush width", ["toolDecrBrushW.png"], None, None) @GuiCommandListDecorator(0, "Decrease brush width", "Decrease brush width", ["toolDecrBrushW.png"], None, None)
@GuiCommandListDecorator(1, "Decrease brush height", "Decrease brush height", ["toolDecrBrushH.png"], None, None) @GuiCommandListDecorator(1, "Decrease brush height", "Decrease brush height", ["toolDecrBrushH.png"], None, None)
@GuiCommandListDecorator(2, "Decrease brush size", "Decrease brush size", ["toolDecrBrushHW.png"], None, None) @GuiCommandListDecorator(2, "Decrease brush size", "Decrease brush size", ["toolDecrBrushHW.png"], [wx.ACCEL_CTRL, ord("-")], None)
@GuiCommandListDecorator(3, "Increase brush width", "Increase brush width", ["toolIncrBrushW.png"], None, None) @GuiCommandListDecorator(3, "Increase brush width", "Increase brush width", ["toolIncrBrushW.png"], None, None)
@GuiCommandListDecorator(4, "Increase brush height", "Increase brush height", ["toolIncrBrushH.png"], None, None) @GuiCommandListDecorator(4, "Increase brush height", "Increase brush height", ["toolIncrBrushH.png"], None, None)
@GuiCommandListDecorator(5, "Increase brush size", "Increase brush size", ["toolIncrBrushHW.png"], None, None) @GuiCommandListDecorator(5, "Increase brush size", "Increase brush size", ["toolIncrBrushHW.png"], [wx.ACCEL_CTRL, ord("+")], None)
def canvasBrushSize(self, f, dimension, incrFlag): def canvasBrushSize(self, f, dimension, incrFlag):
def canvasBrushSize_(event): def canvasBrushSize_(event):
if (dimension < 2) and not incrFlag: if (dimension < 2) and not incrFlag:
@ -49,16 +53,18 @@ class RoarCanvasCommandsEdit():
self.update(brushSize=self.parentCanvas.brushSize) self.update(brushSize=self.parentCanvas.brushSize)
elif dimension == 2: elif dimension == 2:
[self.canvasBrushSize(f, dimension_, incrFlag)(None) for dimension_ in [0, 1]] [self.canvasBrushSize(f, dimension_, incrFlag)(None) for dimension_ in [0, 1]]
viewRect = self.parentCanvas.GetViewStart()
eventDc = self.parentCanvas.backend.getDeviceContext(self.parentCanvas.GetClientSize(), self.parentCanvas, viewRect)
self.parentCanvas.applyTool(eventDc, True, None, None, None, self.parentCanvas.brushPos, False, False, False, self.currentTool, viewRect, force=True)
setattr(canvasBrushSize_, "attrDict", f.attrList[dimension + (0 if not incrFlag else 3)]) setattr(canvasBrushSize_, "attrDict", f.attrList[dimension + (0 if not incrFlag else 3)])
return canvasBrushSize_ return canvasBrushSize_
# }}}
# {{{ canvasCanvasSize(self, f, dimension, incrFlag)
@GuiCommandListDecorator(0, "Decrease canvas height", "Decrease canvas height", ["toolDecrCanvasH.png"], None, None) @GuiCommandListDecorator(0, "Decrease canvas height", "Decrease canvas height", ["toolDecrCanvasH.png"], None, None)
@GuiCommandListDecorator(1, "Decrease canvas width", "Decrease canvas width", ["toolDecrCanvasW.png"], None, None) @GuiCommandListDecorator(1, "Decrease canvas width", "Decrease canvas width", ["toolDecrCanvasW.png"], None, None)
@GuiCommandListDecorator(2, "Decrease canvas size", "Decrease canvas size", ["toolDecrCanvasHW.png"], None, None) @GuiCommandListDecorator(2, "Decrease canvas size", "Decrease canvas size", ["toolDecrCanvasHW.png"], [wx.ACCEL_CTRL | wx.ACCEL_SHIFT, ord("-")], None)
@GuiCommandListDecorator(3, "Increase canvas height", "Increase canvas height", ["toolIncrCanvasH.png"], None, None) @GuiCommandListDecorator(3, "Increase canvas height", "Increase canvas height", ["toolIncrCanvasH.png"], None, None)
@GuiCommandListDecorator(4, "Increase canvas width", "Increase canvas width", ["toolIncrCanvasW.png"], None, None) @GuiCommandListDecorator(4, "Increase canvas width", "Increase canvas width", ["toolIncrCanvasW.png"], None, None)
@GuiCommandListDecorator(5, "Increase canvas size", "Increase canvas size", ["toolIncrCanvasHW.png"], None, None) @GuiCommandListDecorator(5, "Increase canvas size", "Increase canvas size", ["toolIncrCanvasHW.png"], [wx.ACCEL_CTRL | wx.ACCEL_SHIFT, ord("+")], None)
def canvasCanvasSize(self, f, dimension, incrFlag): def canvasCanvasSize(self, f, dimension, incrFlag):
def canvasCanvasSize_(event): def canvasCanvasSize_(event):
if (dimension < 2) and not incrFlag: if (dimension < 2) and not incrFlag:
@ -77,8 +83,7 @@ class RoarCanvasCommandsEdit():
[self.canvasCanvasSize(f, dimension_, incrFlag)(None) for dimension_ in [0, 1]] [self.canvasCanvasSize(f, dimension_, incrFlag)(None) for dimension_ in [0, 1]]
setattr(canvasCanvasSize_, "attrDict", f.attrList[dimension + (0 if not incrFlag else 3)]) setattr(canvasCanvasSize_, "attrDict", f.attrList[dimension + (0 if not incrFlag else 3)])
return canvasCanvasSize_ return canvasCanvasSize_
# }}}
# {{{ canvasColour(self, f, idx)
@GuiSelectDecorator(0, "Colour #00", "Colour #00 (Bright White)", None, [wx.ACCEL_CTRL, ord("0")], False) @GuiSelectDecorator(0, "Colour #00", "Colour #00 (Bright White)", None, [wx.ACCEL_CTRL, ord("0")], False)
@GuiSelectDecorator(1, "Colour #01", "Colour #01 (Black)", None, [wx.ACCEL_CTRL, ord("1")], False) @GuiSelectDecorator(1, "Colour #01", "Colour #01 (Black)", None, [wx.ACCEL_CTRL, ord("1")], False)
@GuiSelectDecorator(2, "Colour #02", "Colour #02 (Blue)", None, [wx.ACCEL_CTRL, ord("2")], False) @GuiSelectDecorator(2, "Colour #02", "Colour #02 (Blue)", None, [wx.ACCEL_CTRL, ord("2")], False)
@ -102,11 +107,13 @@ class RoarCanvasCommandsEdit():
elif event.GetEventType() == wx.wxEVT_TOOL_RCLICKED: elif event.GetEventType() == wx.wxEVT_TOOL_RCLICKED:
self.parentCanvas.brushColours[1] = idx self.parentCanvas.brushColours[1] = idx
self.update(colours=self.parentCanvas.brushColours) self.update(colours=self.parentCanvas.brushColours)
viewRect = self.parentCanvas.GetViewStart()
eventDc = self.parentCanvas.backend.getDeviceContext(self.parentCanvas.GetClientSize(), self.parentCanvas, viewRect)
self.parentCanvas.applyTool(eventDc, True, None, None, None, self.parentCanvas.brushPos, False, False, False, self.currentTool, viewRect, force=True)
setattr(canvasColour_, "attrDict", f.attrList[idx]) setattr(canvasColour_, "attrDict", f.attrList[idx])
setattr(canvasColour_, "isSelect", True) setattr(canvasColour_, "isSelect", True)
return canvasColour_ return canvasColour_
# }}}
# {{{ canvasColourAlpha(self, f, idx)
@GuiSelectDecorator(0, "Transparent colour", "Transparent colour", None, [wx.ACCEL_CTRL | wx.ACCEL_SHIFT, ord("6")], False) @GuiSelectDecorator(0, "Transparent colour", "Transparent colour", None, [wx.ACCEL_CTRL | wx.ACCEL_SHIFT, ord("6")], False)
def canvasColourAlpha(self, f, idx): def canvasColourAlpha(self, f, idx):
def canvasColourAlpha_(event): def canvasColourAlpha_(event):
@ -115,55 +122,105 @@ class RoarCanvasCommandsEdit():
elif event.GetEventType() == wx.wxEVT_TOOL_RCLICKED: elif event.GetEventType() == wx.wxEVT_TOOL_RCLICKED:
self.parentCanvas.brushColours[1] = -1 self.parentCanvas.brushColours[1] = -1
self.update(colours=self.parentCanvas.brushColours) self.update(colours=self.parentCanvas.brushColours)
viewRect = self.parentCanvas.GetViewStart()
eventDc = self.parentCanvas.backend.getDeviceContext(self.parentCanvas.GetClientSize(), self.parentCanvas, viewRect)
self.parentCanvas.applyTool(eventDc, True, None, None, None, self.parentCanvas.brushPos, False, False, False, self.currentTool, viewRect, force=True)
setattr(canvasColourAlpha_, "attrDict", f.attrList[idx]) setattr(canvasColourAlpha_, "attrDict", f.attrList[idx])
setattr(canvasColourAlpha_, "isSelect", True) setattr(canvasColourAlpha_, "isSelect", True)
return canvasColourAlpha_ return canvasColourAlpha_
# }}}
# {{{ canvasCopy(self, event) @GuiSelectDecorator(0, "Transparent colour", "Transparent colour", None, [wx.ACCEL_CTRL | wx.ACCEL_ALT | wx.ACCEL_SHIFT, ord("6")], False)
def canvasColourAlphaBackground(self, f, idx):
def canvasColourAlphaBackground_(event):
self.parentCanvas.brushColours[1] = -1
self.update(colours=self.parentCanvas.brushColours)
viewRect = self.parentCanvas.GetViewStart()
eventDc = self.parentCanvas.backend.getDeviceContext(self.parentCanvas.GetClientSize(), self.parentCanvas, viewRect)
self.parentCanvas.applyTool(eventDc, True, None, None, None, self.parentCanvas.brushPos, False, False, False, self.currentTool, viewRect, force=True)
setattr(canvasColourAlphaBackground_, "attrDict", f.attrList[idx])
setattr(canvasColourAlphaBackground_, "isSelect", True)
return canvasColourAlphaBackground_
@GuiSelectDecorator(0, "Colour #00", "Colour #00 (Bright White)", None, [wx.ACCEL_CTRL | wx.ACCEL_ALT, ord("0")], False)
@GuiSelectDecorator(1, "Colour #01", "Colour #01 (Black)", None, [wx.ACCEL_CTRL | wx.ACCEL_ALT, ord("1")], False)
@GuiSelectDecorator(2, "Colour #02", "Colour #02 (Blue)", None, [wx.ACCEL_CTRL | wx.ACCEL_ALT, ord("2")], False)
@GuiSelectDecorator(3, "Colour #03", "Colour #03 (Green)", None, [wx.ACCEL_CTRL | wx.ACCEL_ALT, ord("3")], False)
@GuiSelectDecorator(4, "Colour #04", "Colour #04 (Red)", None, [wx.ACCEL_CTRL | wx.ACCEL_ALT, ord("4")], False)
@GuiSelectDecorator(5, "Colour #05", "Colour #05 (Light Red)", None, [wx.ACCEL_CTRL | wx.ACCEL_ALT, ord("5")], False)
@GuiSelectDecorator(6, "Colour #06", "Colour #06 (Pink)", None, [wx.ACCEL_CTRL | wx.ACCEL_ALT, ord("6")], False)
@GuiSelectDecorator(7, "Colour #07", "Colour #07 (Yellow)", None, [wx.ACCEL_CTRL | wx.ACCEL_ALT, ord("7")], False)
@GuiSelectDecorator(8, "Colour #08", "Colour #08 (Light Yellow)", None, [wx.ACCEL_CTRL | wx.ACCEL_ALT, ord("8")], False)
@GuiSelectDecorator(9, "Colour #09", "Colour #09 (Light Green)", None, [wx.ACCEL_CTRL | wx.ACCEL_ALT, ord("9")], False)
@GuiSelectDecorator(10, "Colour #10", "Colour #10 (Cyan)", None, [wx.ACCEL_CTRL | wx.ACCEL_ALT | wx.ACCEL_SHIFT, ord("0")], False)
@GuiSelectDecorator(11, "Colour #11", "Colour #11 (Light Cyan)", None, [wx.ACCEL_CTRL | wx.ACCEL_ALT | wx.ACCEL_SHIFT, ord("1")], False)
@GuiSelectDecorator(12, "Colour #12", "Colour #12 (Light Blue)", None, [wx.ACCEL_CTRL | wx.ACCEL_ALT | wx.ACCEL_SHIFT, ord("2")], False)
@GuiSelectDecorator(13, "Colour #13", "Colour #13 (Light Pink)", None, [wx.ACCEL_CTRL | wx.ACCEL_ALT | wx.ACCEL_SHIFT, ord("3")], False)
@GuiSelectDecorator(14, "Colour #14", "Colour #14 (Grey)", None, [wx.ACCEL_CTRL | wx.ACCEL_ALT | wx.ACCEL_SHIFT, ord("4")], False)
@GuiSelectDecorator(15, "Colour #15", "Colour #15 (Light Grey)", None, [wx.ACCEL_CTRL | wx.ACCEL_ALT | wx.ACCEL_SHIFT, ord("5")], False)
def canvasColourBackground(self, f, idx):
def canvasColourBackground_(event):
self.parentCanvas.brushColours[1] = idx
self.update(colours=self.parentCanvas.brushColours)
viewRect = self.parentCanvas.GetViewStart()
eventDc = self.parentCanvas.backend.getDeviceContext(self.parentCanvas.GetClientSize(), self.parentCanvas, viewRect)
self.parentCanvas.applyTool(eventDc, True, None, None, None, self.parentCanvas.brushPos, False, False, False, self.currentTool, viewRect, force=True)
setattr(canvasColourBackground_, "attrDict", f.attrList[idx])
setattr(canvasColourBackground_, "isSelect", True)
return canvasColourBackground_
@GuiCommandDecorator("Flip colours", "Flip colours", ["toolColoursFlip.png"], [wx.ACCEL_CTRL, ord("I")], True)
def canvasColoursFlip(self, event):
self.parentCanvas.brushColours = [self.parentCanvas.brushColours[1], self.parentCanvas.brushColours[0]]
self.update(colours=self.parentCanvas.brushColours)
viewRect = self.parentCanvas.GetViewStart()
eventDc = self.parentCanvas.backend.getDeviceContext(self.parentCanvas.GetClientSize(), self.parentCanvas, viewRect)
self.parentCanvas.applyTool(eventDc, True, None, None, None, self.parentCanvas.brushPos, False, False, False, self.currentTool, viewRect, force=True)
@GuiCommandDecorator("Copy", "&Copy", ["", wx.ART_COPY], None, False) @GuiCommandDecorator("Copy", "&Copy", ["", wx.ART_COPY], None, False)
def canvasCopy(self, event): def canvasCopy(self, event):
pass pass
# }}}
# {{{ canvasCut(self, event)
@GuiCommandDecorator("Cut", "Cu&t", ["", wx.ART_CUT], None, False) @GuiCommandDecorator("Cut", "Cu&t", ["", wx.ART_CUT], None, False)
def canvasCut(self, event): def canvasCut(self, event):
pass pass
# }}}
# {{{ canvasDelete(self, event)
@GuiCommandDecorator("Delete", "De&lete", ["", wx.ART_DELETE], None, False) @GuiCommandDecorator("Delete", "De&lete", ["", wx.ART_DELETE], None, False)
def canvasDelete(self, event): def canvasDelete(self, event):
pass pass
# }}}
# {{{ canvasPaste(self, event)
@GuiCommandDecorator("Paste", "&Paste", ["", wx.ART_PASTE], None, False) @GuiCommandDecorator("Paste", "&Paste", ["", wx.ART_PASTE], None, False)
def canvasPaste(self, event): def canvasPaste(self, event):
pass pass
# }}}
# {{{ canvasRedo(self, event)
@GuiCommandDecorator("Redo", "&Redo", ["", wx.ART_REDO], [wx.ACCEL_CTRL, ord("Y")], False) @GuiCommandDecorator("Redo", "&Redo", ["", wx.ART_REDO], [wx.ACCEL_CTRL, ord("Y")], False)
def canvasRedo(self, event): def canvasRedo(self, event):
self.parentCanvas.dispatchDeltaPatches(self.parentCanvas.canvas.journal.popRedo()) self.parentCanvas.dispatchDeltaPatches(self.parentCanvas.canvas.journal.popRedo())
self.update(size=self.parentCanvas.canvas.size, undoLevel=self.parentCanvas.canvas.journal.patchesUndoLevel) self.update(size=self.parentCanvas.canvas.size, undoLevel=self.parentCanvas.canvas.journal.patchesUndoLevel)
# }}}
# {{{ canvasUndo(self, event)
@GuiCommandDecorator("Undo", "&Undo", ["", wx.ART_UNDO], [wx.ACCEL_CTRL, ord("Z")], False) @GuiCommandDecorator("Undo", "&Undo", ["", wx.ART_UNDO], [wx.ACCEL_CTRL, ord("Z")], False)
def canvasUndo(self, event): def canvasUndo(self, event):
self.parentCanvas.dispatchDeltaPatches(self.parentCanvas.canvas.journal.popUndo()) self.parentCanvas.dispatchDeltaPatches(self.parentCanvas.canvas.journal.popUndo())
self.update(size=self.parentCanvas.canvas.size, undoLevel=self.parentCanvas.canvas.journal.patchesUndoLevel) self.update(size=self.parentCanvas.canvas.size, undoLevel=self.parentCanvas.canvas.journal.patchesUndoLevel)
# }}}
# #
# __init__(self) # __init__(self)
def __init__(self): def __init__(self):
self.accels = (
(self.canvasColourBackground(self.canvasColourBackground, 0), self.canvasColourBackground(self.canvasColourBackground, 1), self.canvasColourBackground(self.canvasColourBackground, 2), self.canvasColourBackground(self.canvasColourBackground, 3), self.canvasColourBackground(self.canvasColourBackground, 4), self.canvasColourBackground(self.canvasColourBackground, 5), self.canvasColourBackground(self.canvasColourBackground, 6), self.canvasColourBackground(self.canvasColourBackground, 7), self.canvasColourBackground(self.canvasColourBackground, 8), self.canvasColourBackground(self.canvasColourBackground, 9), self.canvasColourBackground(self.canvasColourBackground, 10), self.canvasColourBackground(self.canvasColourBackground, 11), self.canvasColourBackground(self.canvasColourBackground, 12), self.canvasColourBackground(self.canvasColourBackground, 13), self.canvasColourBackground(self.canvasColourBackground, 14), self.canvasColourBackground(self.canvasColourBackground, 15), self.canvasColourAlphaBackground(self.canvasColourAlphaBackground, 0),),
)
self.menus = ( self.menus = (
("&Edit", ("&Edit",
self.canvasUndo, self.canvasRedo, NID_MENU_SEP, self.canvasUndo, self.canvasRedo, NID_MENU_SEP,
self.canvasCut, self.canvasCopy, self.canvasPaste, self.canvasCut, self.canvasCopy, self.canvasPaste,
self.canvasDelete, NID_MENU_SEP, self.canvasDelete, NID_MENU_SEP,
("Canvas size", self.canvasCanvasSize(self.canvasCanvasSize, 1, True), self.canvasCanvasSize(self.canvasCanvasSize, 1, False), self.canvasCanvasSize(self.canvasCanvasSize, 0, True), self.canvasCanvasSize(self.canvasCanvasSize, 0, False), NID_MENU_SEP,
self.canvasCanvasSize(self.canvasCanvasSize, 2, True), self.canvasCanvasSize(self.canvasCanvasSize, 2, False),),
("Brush size", self.canvasBrushSize(self.canvasBrushSize, 0, True), self.canvasBrushSize(self.canvasBrushSize, 0, False), self.canvasBrushSize(self.canvasBrushSize, 1, True), self.canvasBrushSize(self.canvasBrushSize, 1, False), NID_MENU_SEP, ("Brush size", self.canvasBrushSize(self.canvasBrushSize, 0, True), self.canvasBrushSize(self.canvasBrushSize, 0, False), self.canvasBrushSize(self.canvasBrushSize, 1, True), self.canvasBrushSize(self.canvasBrushSize, 1, False), NID_MENU_SEP,
self.canvasBrushSize(self.canvasBrushSize, 2, True), self.canvasBrushSize(self.canvasBrushSize, 2, False),), self.canvasBrushSize(self.canvasBrushSize, 2, True), self.canvasBrushSize(self.canvasBrushSize, 2, False),),
("Canvas size", self.canvasCanvasSize(self.canvasCanvasSize, 1, True), self.canvasCanvasSize(self.canvasCanvasSize, 1, False), self.canvasCanvasSize(self.canvasCanvasSize, 0, True), self.canvasCanvasSize(self.canvasCanvasSize, 0, False), NID_MENU_SEP,
self.canvasCanvasSize(self.canvasCanvasSize, 2, True), self.canvasCanvasSize(self.canvasCanvasSize, 2, False),),
self.canvasColoursFlip,
NID_MENU_SEP, NID_MENU_SEP,
self.canvasBrush(self.canvasBrush, 0), NID_MENU_SEP, self.canvasBrush(self.canvasBrush, 0), NID_MENU_SEP,
self.canvasAssetsWindowHide, self.canvasAssetsWindowShow, self.canvasAssetsWindowHide, self.canvasAssetsWindowShow,

View File

@ -21,7 +21,6 @@ from RtlPlatform import getLocalConfPathName
import io, os, wx import io, os, wx
class RoarCanvasCommandsFile(): class RoarCanvasCommandsFile():
# {{{ _import(self, f, newDirty, pathName)
def _import(self, f, newDirty, pathName): def _import(self, f, newDirty, pathName):
rc = False rc = False
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
@ -41,10 +40,9 @@ class RoarCanvasCommandsFile():
dialogChoice = dialog.ShowModal() dialogChoice = dialog.ShowModal()
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
return rc, newPathName return rc, newPathName
# }}}
# {{{ _importFile(self, f, newDirty, wildcard)
def _importFile(self, f, newDirty, wildcard): def _importFile(self, f, newDirty, wildcard):
with wx.FileDialog(self.parentCanvas, "Open", os.getcwd(), "", wildcard, wx.FD_OPEN) as dialog: with wx.FileDialog(self.parentCanvas, "Open...", os.getcwd(), "", wildcard, wx.FD_OPEN) as dialog:
if self.lastDir != None: if self.lastDir != None:
dialog.SetDirectory(self.lastDir) dialog.SetDirectory(self.lastDir)
if dialog.ShowModal() == wx.ID_CANCEL: if dialog.ShowModal() == wx.ID_CANCEL:
@ -52,16 +50,14 @@ class RoarCanvasCommandsFile():
elif self._promptSaveChanges(): elif self._promptSaveChanges():
pathName = dialog.GetPath(); self.lastDir = os.path.dirname(pathName); pathName = dialog.GetPath(); self.lastDir = os.path.dirname(pathName);
return self._import(f, newDirty, pathName) return self._import(f, newDirty, pathName)
# }}}
# {{{ _loadRecent(self)
def _loadRecent(self): def _loadRecent(self):
localConfFileName = getLocalConfPathName("Recent.lst") localConfFileName = getLocalConfPathName("Recent.lst")
if os.path.exists(localConfFileName): if os.path.exists(localConfFileName):
with open(localConfFileName, "r", encoding="utf-8") as inFile: with open(localConfFileName, "r", encoding="utf-8") as inFile:
for lastFile in inFile.readlines(): for lastFile in inFile.readlines():
self._pushRecent(lastFile.rstrip("\r\n"), False) self._pushRecent(lastFile.rstrip("\r\n"), False)
# }}}
# {{{ _promptSaveChanges(self)
def _promptSaveChanges(self): def _promptSaveChanges(self):
if self.parentCanvas.dirty: if self.parentCanvas.dirty:
message = "Do you want to save changes to {}?".format(self.canvasPathName if self.canvasPathName != None else "(Untitled)") message = "Do you want to save changes to {}?".format(self.canvasPathName if self.canvasPathName != None else "(Untitled)")
@ -77,8 +73,7 @@ class RoarCanvasCommandsFile():
return False return False
else: else:
return True return True
# }}}
# {{{ _pushRecent(self, pathName, serialise=True)
def _pushRecent(self, pathName, serialise=True): def _pushRecent(self, pathName, serialise=True):
menuItemId = wx.NewId() menuItemId = wx.NewId()
if not pathName in [l["pathName"] for l in self.lastFiles]: if not pathName in [l["pathName"] for l in self.lastFiles]:
@ -95,16 +90,14 @@ class RoarCanvasCommandsFile():
with open(localConfFileName, "w", encoding="utf-8") as outFile: with open(localConfFileName, "w", encoding="utf-8") as outFile:
for lastFile in [l["pathName"] for l in self.lastFiles]: for lastFile in [l["pathName"] for l in self.lastFiles]:
print(lastFile, file=outFile) print(lastFile, file=outFile)
# }}}
# {{{ canvasExit(self, event)
@GuiCommandDecorator("Exit", "E&xit", None, [wx.ACCEL_CTRL, ord("X")], None) @GuiCommandDecorator("Exit", "E&xit", None, [wx.ACCEL_CTRL, ord("X")], None)
def canvasExit(self, event): def canvasExit(self, event):
if self._promptSaveChanges(): if self._promptSaveChanges():
self.parentFrame.Close(True) self.parentFrame.Close(True)
# }}}
# {{{ canvasExportAsAnsi(self, event)
@GuiCommandDecorator("Export as ANSI...", "Export as &ANSI...", None, None, None) @GuiCommandDecorator("Export as ANSI...", "Export as &ANSI...", None, None, None)
def canvasExportAsAnsi(self, event): def canvasExportAsAnsi(self, event):
with wx.FileDialog(self.parentFrame, "Save As...", os.getcwd(), "", "ANSI files (*.ans;*.txt)|*.ans;*.txt|All Files (*.*)|*.*", wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) as dialog: with wx.FileDialog(self.parentFrame, "Save As...", os.getcwd(), "", "ANSI files (*.ans;*.txt)|*.ans;*.txt|All Files (*.*)|*.*", wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) as dialog:
@ -119,8 +112,7 @@ class RoarCanvasCommandsFile():
self.parentCanvas.canvas.exportStore.exportAnsiFile(self.parentCanvas.canvas.map, self.parentCanvas.canvas.size, 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
# }}}
# {{{ canvasExportAsPng(self, event)
@GuiCommandDecorator("Export as PNG...", "Export as PN&G...", None, None, None) @GuiCommandDecorator("Export as PNG...", "Export as PN&G...", None, None, None)
def canvasExportAsPng(self, event): def canvasExportAsPng(self, event):
with wx.FileDialog(self.parentFrame, "Save As...", os.getcwd(), "", "PNG (*.png)|*.png|All Files (*.*)|*.*", wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) as dialog: with wx.FileDialog(self.parentFrame, "Save As...", os.getcwd(), "", "PNG (*.png)|*.png|All Files (*.*)|*.*", wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) as dialog:
@ -134,8 +126,7 @@ class RoarCanvasCommandsFile():
self.parentCanvas.canvas.exportStore.exportBitmapToPngFile(self.parentCanvas.backend.canvasBitmap, outPathName, wx.BITMAP_TYPE_PNG) self.parentCanvas.canvas.exportStore.exportBitmapToPngFile(self.parentCanvas.backend.canvasBitmap, outPathName, wx.BITMAP_TYPE_PNG)
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
return True return True
# }}}
# {{{ canvasExportImgur(self, event)
@GuiCommandDecorator("Export to Imgur...", "Export to I&mgur...", None, None, haveImgurApiKey and haveUrllib) @GuiCommandDecorator("Export to Imgur...", "Export to I&mgur...", None, None, haveImgurApiKey and haveUrllib)
def canvasExportImgur(self, event): def canvasExportImgur(self, event):
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
@ -147,8 +138,7 @@ class RoarCanvasCommandsFile():
wx.MessageBox("Exported to Imgur: {}".format(result), "Export to Imgur", wx.ICON_INFORMATION | wx.OK) wx.MessageBox("Exported to Imgur: {}".format(result), "Export to Imgur", wx.ICON_INFORMATION | wx.OK)
else: else:
wx.MessageBox("Failed to export to Imgur: {}".format(result), "Export to Imgur", wx.ICON_EXCLAMATION | wx.OK) wx.MessageBox("Failed to export to Imgur: {}".format(result), "Export to Imgur", wx.ICON_EXCLAMATION | wx.OK)
# }}}
# {{{ canvasExportPastebin(self, event)
@GuiCommandDecorator("Export to Pastebin...", "Export to Pasteb&in...", None, None, haveUrllib) @GuiCommandDecorator("Export to Pastebin...", "Export to Pasteb&in...", None, None, haveUrllib)
def canvasExportPastebin(self, event): def canvasExportPastebin(self, event):
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
@ -162,8 +152,7 @@ class RoarCanvasCommandsFile():
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: 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)
@GuiCommandDecorator("Export to clipboard", "Export to &clipboard", None, None, None) @GuiCommandDecorator("Export to clipboard", "Export to &clipboard", None, None, None)
def canvasExportToClipboard(self, event): def canvasExportToClipboard(self, event):
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT)) self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
@ -173,17 +162,15 @@ class RoarCanvasCommandsFile():
wx.TheClipboard.Close() wx.TheClipboard.Close()
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor)) self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
return True return True
# }}}
# {{{ canvasImportAnsi(self, event)
@GuiCommandDecorator("Import ANSI...", "Import &ANSI...", None, None, None) @GuiCommandDecorator("Import ANSI...", "Import &ANSI...", None, None, None)
def canvasImportAnsi(self, event): def canvasImportAnsi(self, event):
def canvasImportAnsi_(pathName): def canvasImportAnsi_(pathName):
rc, error = self.parentCanvas.canvas.importStore.importAnsiFile(pathName) rc, error = self.parentCanvas.canvas.importStore.importAnsiFile(pathName)
return (rc, error, self.parentCanvas.canvas.importStore.outMap, pathName, self.parentCanvas.canvas.importStore.inSize) return (rc, error, self.parentCanvas.canvas.importStore.outMap, pathName, self.parentCanvas.canvas.importStore.inSize)
self._importFile(canvasImportAnsi_, True, "ANSI files (*.ans;*.txt)|*.ans;*.txt|All Files (*.*)|*.*") self._importFile(canvasImportAnsi_, True, "ANSI files (*.ans;*.txt)|*.ans;*.txt|All Files (*.*)|*.*")
# }}}
# {{{ canvasImportFromClipboard(self, event)
@GuiCommandDecorator("Import from clipboard", "Import from &clipboard", None, None, None) @GuiCommandDecorator("Import from clipboard", "Import from &clipboard", None, None, None)
def canvasImportFromClipboard(self, event): def canvasImportFromClipboard(self, event):
def canvasImportFromClipboard_(pathName): def canvasImportFromClipboard_(pathName):
@ -199,17 +186,15 @@ class RoarCanvasCommandsFile():
return (rc, error, self.parentCanvas.canvas.importStore.outMap, None, self.parentCanvas.canvas.importStore.inSize) return (rc, error, self.parentCanvas.canvas.importStore.outMap, None, self.parentCanvas.canvas.importStore.inSize)
if self._promptSaveChanges(): if self._promptSaveChanges():
self._import(canvasImportFromClipboard_, True, None) self._import(canvasImportFromClipboard_, True, None)
# }}}
# {{{ canvasImportSauce(self, event)
@GuiCommandDecorator("Import SAUCE...", "Import &SAUCE...", None, None, None) @GuiCommandDecorator("Import SAUCE...", "Import &SAUCE...", None, None, None)
def canvasImportSauce(self, event): def canvasImportSauce(self, event):
def canvasImportSauce_(pathName): def canvasImportSauce_(pathName):
rc, error = self.parentCanvas.canvas.importStore.importSauceFile(pathName) rc, error = self.parentCanvas.canvas.importStore.importSauceFile(pathName)
return (rc, error, self.parentCanvas.canvas.importStore.outMap, pathName, self.parentCanvas.canvas.importStore.inSize) return (rc, error, self.parentCanvas.canvas.importStore.outMap, pathName, self.parentCanvas.canvas.importStore.inSize)
self._importFile(canvasImportSauce_, True, "SAUCE files (*.ans;*.txt)|*.ans;*.txt|All Files (*.*)|*.*") self._importFile(canvasImportSauce_, True, "SAUCE files (*.ans;*.txt)|*.ans;*.txt|All Files (*.*)|*.*")
# }}}
# {{{ canvasNew(self, event, newCanvasSize=None)
@GuiCommandDecorator("New", "&New", ["", wx.ART_NEW], [wx.ACCEL_CTRL, ord("N")], None) @GuiCommandDecorator("New", "&New", ["", wx.ART_NEW], [wx.ACCEL_CTRL, ord("N")], None)
def canvasNew(self, event, newCanvasSize=None): def canvasNew(self, event, newCanvasSize=None):
def canvasImportEmpty(pathName): def canvasImportEmpty(pathName):
@ -220,8 +205,7 @@ class RoarCanvasCommandsFile():
return (True, "", newMap, None, newCanvasSize) return (True, "", newMap, None, newCanvasSize)
if self._promptSaveChanges(): if self._promptSaveChanges():
self._import(canvasImportEmpty, False, None) self._import(canvasImportEmpty, False, None)
# }}}
# {{{ canvasOpen(self, event)
@GuiCommandDecorator("Open", "&Open", ["", wx.ART_FILE_OPEN], [wx.ACCEL_CTRL, ord("O")], None) @GuiCommandDecorator("Open", "&Open", ["", wx.ART_FILE_OPEN], [wx.ACCEL_CTRL, ord("O")], None)
def canvasOpen(self, event): def canvasOpen(self, event):
def canvasImportmIRC(pathName): def canvasImportmIRC(pathName):
@ -230,16 +214,14 @@ class RoarCanvasCommandsFile():
rc, newPathName = self._importFile(canvasImportmIRC, False, "mIRC art files (*.txt)|*.txt|All Files (*.*)|*.*") rc, newPathName = self._importFile(canvasImportmIRC, False, "mIRC art files (*.txt)|*.txt|All Files (*.*)|*.*")
if rc: if rc:
self._pushRecent(newPathName) self._pushRecent(newPathName)
# }}}
# {{{ canvasOpenRecent(self, event, pathName=None)
@GuiSubMenuDecorator("Open Recent", "Open &Recent", None, None, False) @GuiSubMenuDecorator("Open Recent", "Open &Recent", None, None, False)
def canvasOpenRecent(self, event, pathName=None): def canvasOpenRecent(self, event, pathName=None):
def canvasImportmIRC(pathName): def canvasImportmIRC(pathName):
rc, error = self.parentCanvas.canvas.importStore.importTextFile(pathName) rc, error = self.parentCanvas.canvas.importStore.importTextFile(pathName)
return (rc, error, self.parentCanvas.canvas.importStore.outMap, pathName, self.parentCanvas.canvas.importStore.inSize) return (rc, error, self.parentCanvas.canvas.importStore.outMap, pathName, self.parentCanvas.canvas.importStore.inSize)
self._import(canvasImportmIRC, False, pathName) self._import(canvasImportmIRC, False, pathName)
# }}}
# {{{ canvasSave(self, event)
@GuiCommandDecorator("Save", "&Save", ["", wx.ART_FILE_SAVE], [wx.ACCEL_CTRL, ord("S")], None) @GuiCommandDecorator("Save", "&Save", ["", wx.ART_FILE_SAVE], [wx.ACCEL_CTRL, ord("S")], None)
def canvasSave(self, event, newDirty=False): def canvasSave(self, event, newDirty=False):
if self.canvasPathName == None: if self.canvasPathName == None:
@ -256,8 +238,7 @@ class RoarCanvasCommandsFile():
return True return True
except IOError as error: except IOError as error:
return False return False
# }}}
# {{{ canvasSaveAs(self, event)
@GuiCommandDecorator("Save As...", "Save &As...", ["", wx.ART_FILE_SAVE_AS], None, None) @GuiCommandDecorator("Save As...", "Save &As...", ["", wx.ART_FILE_SAVE_AS], None, None)
def canvasSaveAs(self, event): 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: 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:
@ -269,12 +250,13 @@ class RoarCanvasCommandsFile():
self.canvasPathName = dialog.GetPath(); self.lastDir = os.path.dirname(self.canvasPathName); self.canvasPathName = dialog.GetPath(); self.lastDir = os.path.dirname(self.canvasPathName);
if self.canvasSave(event, newDirty=True): if self.canvasSave(event, newDirty=True):
self._pushRecent(self.canvasPathName) self._pushRecent(self.canvasPathName)
# }}}
# #
# __init__(self) # __init__(self)
def __init__(self): def __init__(self):
self.imgurApiKey, self.lastFiles, self.lastDir = ImgurApiKey.imgurApiKey if haveImgurApiKey else None, [], None self.imgurApiKey, self.lastFiles, self.lastDir = ImgurApiKey.imgurApiKey if haveImgurApiKey else None, [], None
self.accels = ()
self.menus = ( self.menus = (
("&File", ("&File",
self.canvasNew, self.canvasOpen, self.canvasOpenRecent, self.canvasSave, self.canvasSaveAs, NID_MENU_SEP, self.canvasNew, self.canvasOpen, self.canvasOpenRecent, self.canvasSave, self.canvasSaveAs, NID_MENU_SEP,

View File

@ -8,15 +8,15 @@ from GuiFrame import GuiCommandDecorator
from RoarWindowAbout import RoarWindowAbout from RoarWindowAbout import RoarWindowAbout
class RoarCanvasCommandsHelp(): class RoarCanvasCommandsHelp():
# {{{ canvasAbout(self, event)
@GuiCommandDecorator("About", "&About", None, None, True) @GuiCommandDecorator("About", "&About", None, None, True)
def canvasAbout(self, event): def canvasAbout(self, event):
RoarWindowAbout(self.parentFrame) RoarWindowAbout(self.parentFrame)
# }}}
# #
# __init__(self) # __init__(self)
def __init__(self): def __init__(self):
self.accels = ()
self.menus, self.toolBars = (("&Help", self.canvasAbout,),), () self.menus, self.toolBars = (("&Help", self.canvasAbout,),), ()
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=0 # vim:expandtab foldmethod=marker sw=4 ts=4 tw=0

View File

@ -14,10 +14,9 @@ from ToolObject import ToolObject
import copy, wx import copy, wx
class RoarCanvasCommandsOperators(): class RoarCanvasCommandsOperators():
# {{{ canvasOperator(self, f, idx)
@GuiCommandListDecorator(0, "Flip", "&Flip", None, None, None) @GuiCommandListDecorator(0, "Flip", "&Flip", None, None, None)
@GuiCommandListDecorator(1, "Flip horizontally", "Flip &horizontally", None, None, None) @GuiCommandListDecorator(1, "Flip horizontally", "Flip &horizontally", None, None, None)
@GuiCommandListDecorator(2, "Invert", "&Invert", None, None, None) @GuiCommandListDecorator(2, "Invert colours", "&Invert colours", None, None, None)
@GuiCommandListDecorator(3, "Rotate", "&Rotate", None, None, None) @GuiCommandListDecorator(3, "Rotate", "&Rotate", None, None, None)
@GuiCommandListDecorator(4, "Tile", "&Tile", None, None, None) @GuiCommandListDecorator(4, "Tile", "&Tile", None, None, None)
def canvasOperator(self, f, idx): def canvasOperator(self, f, idx):
@ -27,11 +26,12 @@ class RoarCanvasCommandsOperators():
self.parentCanvas.applyOperator(self.currentTool, self.parentCanvas.brushPos, None, False, self.currentOperator, self.parentCanvas.GetViewStart()) self.parentCanvas.applyOperator(self.currentTool, self.parentCanvas.brushPos, None, False, self.currentOperator, self.parentCanvas.GetViewStart())
setattr(canvasOperator_, "attrDict", f.attrList[idx]) setattr(canvasOperator_, "attrDict", f.attrList[idx])
return canvasOperator_ return canvasOperator_
# }}}
# #
# __init__(self) # __init__(self)
def __init__(self): def __init__(self):
self.accels = ()
self.menus = ( self.menus = (
("&Operators", ("&Operators",
self.canvasOperator(self.canvasOperator, 0), self.canvasOperator(self.canvasOperator, 1), self.canvasOperator(self.canvasOperator, 2), self.canvasOperator(self.canvasOperator, 3), self.canvasOperator(self.canvasOperator, 4), self.canvasOperator(self.canvasOperator, 0), self.canvasOperator(self.canvasOperator, 1), self.canvasOperator(self.canvasOperator, 2), self.canvasOperator(self.canvasOperator, 3), self.canvasOperator(self.canvasOperator, 4),

View File

@ -14,7 +14,6 @@ from ToolText import ToolText
import wx import wx
class RoarCanvasCommandsTools(): class RoarCanvasCommandsTools():
# {{{ canvasTool(self, f, idx)
@GuiSelectDecorator(0, "Circle", "&Circle", ["toolCircle.png"], [wx.ACCEL_CTRL, ord("C")], False) @GuiSelectDecorator(0, "Circle", "&Circle", ["toolCircle.png"], [wx.ACCEL_CTRL, ord("C")], False)
@GuiSelectDecorator(1, "Cursor", "C&ursor", ["toolCursor.png"], [wx.ACCEL_CTRL, ord("U")], False) @GuiSelectDecorator(1, "Cursor", "C&ursor", ["toolCursor.png"], [wx.ACCEL_CTRL, ord("U")], False)
@GuiSelectDecorator(2, "Fill", "&Fill", ["toolFill.png"], [wx.ACCEL_CTRL, ord("F")], False) @GuiSelectDecorator(2, "Fill", "&Fill", ["toolFill.png"], [wx.ACCEL_CTRL, ord("F")], False)
@ -33,23 +32,24 @@ class RoarCanvasCommandsTools():
self.currentTool = self.currentTool() self.currentTool = self.currentTool()
self.currentOperator, self.operatorState = None, None self.currentOperator, self.operatorState = None, None
self.parentFrame.menuItemsById[self.canvasTool.attrList[idx]["id"]].Check(True) self.parentFrame.menuItemsById[self.canvasTool.attrList[idx]["id"]].Check(True)
toolBar = self.parentFrame.toolBarItemsById[self.canvasTool.attrList[idx]["id"]].GetToolBar() toolBar = self.parentFrame.toolBarItemsById[self.canvasTool.attrList[idx]["id"]][0]
toolBar.ToggleTool(self.canvasTool.attrList[idx]["id"], True) toolBar.ToggleTool(self.canvasTool.attrList[idx]["id"], True); toolBar.Refresh();
if self.currentTool != None: if self.currentTool != None:
self.update(toolName=self.currentTool.name) self.update(toolName=self.currentTool.name)
viewRect = self.parentCanvas.GetViewStart()
eventDc = self.parentCanvas.backend.getDeviceContext(self.parentCanvas.GetClientSize(), self.parentCanvas, viewRect)
self.parentCanvas.applyTool(eventDc, True, None, None, None, self.parentCanvas.brushPos, False, False, False, self.currentTool, viewRect)
else: else:
self.update(toolName="Cursor") self.update(toolName="Cursor")
viewRect = self.parentCanvas.GetViewStart()
eventDc = self.parentCanvas.backend.getDeviceContext(self.parentCanvas.GetClientSize(), self.parentCanvas, viewRect)
self.parentCanvas.applyTool(eventDc, True, None, None, None, self.parentCanvas.brushPos, False, False, False, self.currentTool, viewRect, force=True)
setattr(canvasTool_, "attrDict", f.attrList[idx]) setattr(canvasTool_, "attrDict", f.attrList[idx])
setattr(canvasTool_, "isSelect", True) setattr(canvasTool_, "isSelect", True)
return canvasTool_ return canvasTool_
# }}}
# #
# __init__(self) # __init__(self)
def __init__(self): def __init__(self):
self.accels = ()
self.menus = ( self.menus = (
("&Tools", ("&Tools",
self.canvasTool(self.canvasTool, 1), self.canvasTool(self.canvasTool, 5), self.canvasTool(self.canvasTool, 0), self.canvasTool(self.canvasTool, 2), self.canvasTool(self.canvasTool, 3), self.canvasTool(self.canvasTool, 6), self.canvasTool(self.canvasTool, 4), self.canvasTool(self.canvasTool, 1), self.canvasTool(self.canvasTool, 5), self.canvasTool(self.canvasTool, 0), self.canvasTool(self.canvasTool, 2), self.canvasTool(self.canvasTool, 3), self.canvasTool(self.canvasTool, 6), self.canvasTool(self.canvasTool, 4),

View File

@ -10,11 +10,9 @@ from ToolText import ToolText
import copy, json, wx, sys import copy, json, wx, sys
class RoarCanvasWindowDropTarget(wx.TextDropTarget): class RoarCanvasWindowDropTarget(wx.TextDropTarget):
# {{{ done(self)
def done(self): def done(self):
self.inProgress = False self.inProgress = False
# }}}
# {{{ OnDropText(self, x, y, data)
def OnDropText(self, x, y, data): def OnDropText(self, x, y, data):
rc = False rc = False
if ((self.parent.commands.currentTool.__class__ != ToolObject) \ if ((self.parent.commands.currentTool.__class__ != ToolObject) \
@ -37,14 +35,12 @@ class RoarCanvasWindowDropTarget(wx.TextDropTarget):
with wx.MessageDialog(self.parent, "Error: {}".format(sys.exc_info()[1]), "", wx.OK | wx.OK_DEFAULT) as dialog: with wx.MessageDialog(self.parent, "Error: {}".format(sys.exc_info()[1]), "", wx.OK | wx.OK_DEFAULT) as dialog:
dialogChoice = dialog.ShowModal() dialogChoice = dialog.ShowModal()
return rc return rc
# }}}
# {{{ __init__(self, parent)
def __init__(self, parent): def __init__(self, parent):
super().__init__(); self.inProgress, self.parent = False, parent; super().__init__(); self.inProgress, self.parent = False, parent;
# }}}
class RoarCanvasWindow(GuiWindow): class RoarCanvasWindow(GuiWindow):
# {{{ _drawPatch(self, eventDc, isCursor, patch)
def _drawPatch(self, eventDc, isCursor, patch): def _drawPatch(self, eventDc, isCursor, patch):
if not self.canvas.dirtyCursor: if not self.canvas.dirtyCursor:
self.backend.drawCursorMaskWithJournal(self.canvas, self.canvas.journal, eventDc) self.backend.drawCursorMaskWithJournal(self.canvas, self.canvas.journal, eventDc)
@ -52,9 +48,8 @@ class RoarCanvasWindow(GuiWindow):
if self.backend.drawPatch(self.canvas, eventDc, patch) and isCursor: if self.backend.drawPatch(self.canvas, eventDc, patch) and isCursor:
patchDeltaCell = self.canvas.map[patch[1]][patch[0]]; patchDelta = [*patch[0:2], *patchDeltaCell]; patchDeltaCell = self.canvas.map[patch[1]][patch[0]]; patchDelta = [*patch[0:2], *patchDeltaCell];
self.canvas.journal.pushCursor(patchDelta) self.canvas.journal.pushCursor(patchDelta)
# }}}
# {{{ applyOperator(self, currentTool, mapPoint, mouseLeftDown, mousePoint, operator, viewRect)
def applyOperator(self, currentTool, mapPoint, mouseLeftDown, mousePoint, operator, viewRect): def applyOperator(self, currentTool, mapPoint, mouseLeftDown, mousePoint, operator, viewRect):
self.canvas.dirtyCursor = False self.canvas.dirtyCursor = False
if (currentTool.__class__ == ToolObject) \ if (currentTool.__class__ == ToolObject) \
@ -94,15 +89,14 @@ class RoarCanvasWindow(GuiWindow):
self.canvas.journal.end() self.canvas.journal.end()
self.commands.update(dirty=self.dirty, undoLevel=self.canvas.journal.patchesUndoLevel) self.commands.update(dirty=self.dirty, undoLevel=self.canvas.journal.patchesUndoLevel)
eventDc.SetDeviceOrigin(*eventDcOrigin) eventDc.SetDeviceOrigin(*eventDcOrigin)
# }}}
# {{{ applyTool(self, eventDc, eventMouse, keyChar, keyCode, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown, tool, viewRect) def applyTool(self, eventDc, eventMouse, keyChar, keyCode, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown, tool, viewRect, force=False):
def applyTool(self, eventDc, eventMouse, keyChar, keyCode, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown, tool, viewRect):
eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0); eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0);
if mapPoint != None:
mapPoint = [a + b for a, b in zip(mapPoint, viewRect)]
dirty, self.canvas.dirtyCursor, rc = False, False, False dirty, self.canvas.dirtyCursor, rc = False, False, False
self.canvas.journal.begin() self.canvas.journal.begin()
if eventMouse: if eventMouse:
if force:
self.lastCellState = None
if ((mapPoint[0] < self.canvas.size[0]) \ if ((mapPoint[0] < self.canvas.size[0]) \
and (mapPoint[1] < self.canvas.size[1])) \ and (mapPoint[1] < self.canvas.size[1])) \
and ((self.lastCellState == None) \ and ((self.lastCellState == None) \
@ -140,8 +134,7 @@ class RoarCanvasWindow(GuiWindow):
self.commands.update(undoInhibit=False) self.commands.update(undoInhibit=False)
eventDc.SetDeviceOrigin(*eventDcOrigin) eventDc.SetDeviceOrigin(*eventDcOrigin)
return rc return rc
# }}}
# {{{ dispatchDeltaPatches(self, deltaPatches)
def dispatchDeltaPatches(self, deltaPatches): def dispatchDeltaPatches(self, deltaPatches):
eventDc = self.backend.getDeviceContext(self.GetClientSize(), self) eventDc = self.backend.getDeviceContext(self.GetClientSize(), self)
eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0); eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0);
@ -158,19 +151,17 @@ class RoarCanvasWindow(GuiWindow):
else: else:
self.canvas._commitPatch(patch); self.backend.drawPatch(self.canvas, eventDc, patch) self.canvas._commitPatch(patch); self.backend.drawPatch(self.canvas, eventDc, patch)
eventDc.SetDeviceOrigin(*eventDcOrigin) eventDc.SetDeviceOrigin(*eventDcOrigin)
# }}}
# {{{ dispatchPatch(self, eventDc, isCursor, patch)
def dispatchPatch(self, eventDc, isCursor, patch): def dispatchPatch(self, eventDc, isCursor, patch):
if self.canvas.dispatchPatch(isCursor, patch, False if isCursor else True): if self.canvas.dispatchPatch(isCursor, patch, False if isCursor else True):
self._drawPatch(eventDc, isCursor, patch) self._drawPatch(eventDc, isCursor, patch)
# }}}
# {{{ dispatchPatchSingle(self, eventDc, isCursor, patch)
def dispatchPatchSingle(self, eventDc, isCursor, patch): def dispatchPatchSingle(self, eventDc, isCursor, patch):
if self.canvas.dispatchPatchSingle(isCursor, patch, False if isCursor else True): if self.canvas.dispatchPatchSingle(isCursor, patch, False if isCursor else True):
self._drawPatch(eventDc, isCursor, patch) self._drawPatch(eventDc, isCursor, patch)
# }}}
# {{{ resize(self, newSize, commitUndo=True)
def resize(self, newSize, commitUndo=True): def resize(self, newSize, commitUndo=True):
viewRect = self.GetViewStart()
oldSize = [0, 0] if self.canvas.map == None else self.canvas.size oldSize = [0, 0] if self.canvas.map == None else self.canvas.size
deltaSize = [b - a for a, b in zip(oldSize, newSize)] deltaSize = [b - a for a, b in zip(oldSize, newSize)]
if self.canvas.resize(newSize, commitUndo): if self.canvas.resize(newSize, commitUndo):
@ -187,9 +178,9 @@ class RoarCanvasWindow(GuiWindow):
for numNewCol in range(newSize[0]): for numNewCol in range(newSize[0]):
self._drawPatch(eventDc, False, [numNewCol, numNewRow, 1, 1, 0, " "]) self._drawPatch(eventDc, False, [numNewCol, numNewRow, 1, 1, 0, " "])
eventDc.SetDeviceOrigin(*eventDcOrigin) eventDc.SetDeviceOrigin(*eventDcOrigin)
self.Scroll(*viewRect)
self.commands.update(size=newSize, undoLevel=self.canvas.journal.patchesUndoLevel) self.commands.update(size=newSize, undoLevel=self.canvas.journal.patchesUndoLevel)
# }}}
# {{{ update(self, newSize, commitUndo=True, newCanvas=None)
def update(self, newSize, commitUndo=True, newCanvas=None): def update(self, newSize, commitUndo=True, newCanvas=None):
self.resize(newSize, commitUndo) self.resize(newSize, commitUndo)
self.canvas.update(newSize, newCanvas) self.canvas.update(newSize, newCanvas)
@ -199,9 +190,8 @@ class RoarCanvasWindow(GuiWindow):
for numCol in range(newSize[0]): for numCol in range(newSize[0]):
self.backend.drawPatch(self.canvas, eventDc, [numCol, numRow, *self.canvas.map[numRow][numCol]]) self.backend.drawPatch(self.canvas, eventDc, [numCol, numRow, *self.canvas.map[numRow][numCol]])
eventDc.SetDeviceOrigin(*eventDcOrigin) eventDc.SetDeviceOrigin(*eventDcOrigin)
# }}}
# {{{ onKeyboardInput(self, event)
def onKeyboardInput(self, event): def onKeyboardInput(self, event):
keyCode, keyModifiers = event.GetKeyCode(), event.GetModifiers() keyCode, keyModifiers = event.GetKeyCode(), event.GetModifiers()
viewRect = self.GetViewStart(); eventDc = self.backend.getDeviceContext(self.GetClientSize(), self, viewRect); viewRect = self.GetViewStart(); eventDc = self.backend.getDeviceContext(self.GetClientSize(), self, viewRect);
@ -245,12 +235,10 @@ class RoarCanvasWindow(GuiWindow):
else: else:
if not self.applyTool(eventDc, False, chr(event.GetUnicodeKey()), keyCode, keyModifiers, None, None, None, None, self.commands.currentTool, viewRect): if not self.applyTool(eventDc, False, chr(event.GetUnicodeKey()), keyCode, keyModifiers, None, None, None, None, self.commands.currentTool, viewRect):
event.Skip() event.Skip()
# }}}
# {{{ onEnterWindow(self, event)
def onEnterWindow(self, event): def onEnterWindow(self, event):
self.lastCellState = None self.lastCellState = None
# }}}
# {{{ onLeaveWindow(self, event)
def onLeaveWindow(self, event): def onLeaveWindow(self, event):
if False: if False:
eventDc = self.backend.getDeviceContext(self.GetClientSize(), self, self.GetViewStart()) eventDc = self.backend.getDeviceContext(self.GetClientSize(), self, self.GetViewStart())
@ -258,12 +246,13 @@ class RoarCanvasWindow(GuiWindow):
self.backend.drawCursorMaskWithJournal(self.canvas, self.canvas.journal, eventDc) self.backend.drawCursorMaskWithJournal(self.canvas, self.canvas.journal, eventDc)
eventDc.SetDeviceOrigin(*eventDcOrigin) eventDc.SetDeviceOrigin(*eventDcOrigin)
self.lastCellState = None self.lastCellState = None
# }}}
# {{{ onMouseInput(self, event)
def onMouseInput(self, event): def onMouseInput(self, event):
viewRect = self.GetViewStart(); eventDc = self.backend.getDeviceContext(self.GetClientSize(), self, viewRect); viewRect = self.GetViewStart(); eventDc = self.backend.getDeviceContext(self.GetClientSize(), self, viewRect);
mouseDragging, mouseLeftDown, mouseRightDown = event.Dragging(), event.LeftIsDown(), event.RightIsDown() mouseDragging, mouseLeftDown, mouseRightDown = event.Dragging(), event.LeftIsDown(), event.RightIsDown()
mapPoint = self.backend.xlateEventPoint(event, eventDc, viewRect) mapPoint = self.backend.xlateEventPoint(event, eventDc, viewRect)
if viewRect != (0, 0):
mapPoint = [a + b for a, b in zip(mapPoint, viewRect)]
if self.commands.currentOperator != None: if self.commands.currentOperator != None:
self.applyOperator(self.commands.currentTool, mapPoint, mouseLeftDown, event.GetLogicalPosition(eventDc), self.commands.currentOperator, viewRect) self.applyOperator(self.commands.currentTool, mapPoint, mouseLeftDown, event.GetLogicalPosition(eventDc), self.commands.currentOperator, viewRect)
elif mouseRightDown \ elif mouseRightDown \
@ -272,8 +261,7 @@ class RoarCanvasWindow(GuiWindow):
self.popupEventDc = eventDc; self.PopupMenu(self.operatorsMenu); self.popupEventDc = None; self.popupEventDc = eventDc; self.PopupMenu(self.operatorsMenu); self.popupEventDc = None;
elif not self.applyTool(eventDc, True, None, None, event.GetModifiers(), mapPoint, mouseDragging, mouseLeftDown, mouseRightDown, self.commands.currentTool, viewRect): elif not self.applyTool(eventDc, True, None, None, event.GetModifiers(), mapPoint, mouseDragging, mouseLeftDown, mouseRightDown, self.commands.currentTool, viewRect):
event.Skip() event.Skip()
# }}}
# {{{ onMouseWheel(self, event)
def onMouseWheel(self, event): def onMouseWheel(self, event):
if event.GetModifiers() == wx.MOD_CONTROL: if event.GetModifiers() == wx.MOD_CONTROL:
cd = +1 if event.GetWheelRotation() >= event.GetWheelDelta() else -1 cd = +1 if event.GetWheelRotation() >= event.GetWheelDelta() else -1
@ -290,15 +278,14 @@ class RoarCanvasWindow(GuiWindow):
eventDc.SetDeviceOrigin(*eventDcOrigin) eventDc.SetDeviceOrigin(*eventDcOrigin)
else: else:
event.Skip() event.Skip()
# }}}
# {{{ onPaint(self, event)
def onPaint(self, event): def onPaint(self, event):
eventDc = self.backend.getDeviceContext(self.GetClientSize(), self) eventDc = self.backend.getDeviceContext(self.GetClientSize(), self)
eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0); eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0);
self.backend.drawCursorMaskWithJournal(self.canvas, self.canvas.journal, eventDc) self.backend.drawCursorMaskWithJournal(self.canvas, self.canvas.journal, eventDc)
eventDc.SetDeviceOrigin(*eventDcOrigin) eventDc.SetDeviceOrigin(*eventDcOrigin)
self.backend.onPaint(self.GetClientSize(), self, self.GetViewStart()) self.backend.onPaint(self.GetClientSize(), self, self.GetViewStart())
# }}}
# #
# __init__(self, backend, canvas, cellSize, commands, parent, parentFrame, pos, scrollStep, size): initialisation method # __init__(self, backend, canvas, cellSize, commands, parent, parentFrame, pos, scrollStep, size): initialisation method

View File

@ -15,27 +15,23 @@ from glob import glob
import os, random, sys, wx import os, random, sys, wx
class RoarClient(GuiFrame): class RoarClient(GuiFrame):
# {{{ _getIconPathName(self)
def _getIconPathName(self): def _getIconPathName(self):
iconPathNames = glob(os.path.join("assets", "images", "logo*.bmp")) iconPathNames = glob(os.path.join("assets", "images", "logo*.bmp"))
return iconPathNames[random.randint(0, len(iconPathNames) - 1)] return iconPathNames[random.randint(0, len(iconPathNames) - 1)]
# }}}
# {{{ _initToolBitmaps(self, toolBars)
def _initToolBitmaps(self, toolBars): def _initToolBitmaps(self, toolBars):
basePathName = os.path.join(os.path.dirname(sys.argv[0]), "assets", "images") basePathName = os.path.join(os.path.dirname(sys.argv[0]), "assets", "images")
for toolBar in toolBars: for toolBar in toolBars:
for toolBarItem in [i for i in toolBar if i != NID_TOOLBAR_HSEP]: for toolBarItem in [i for i in toolBar if i != NID_TOOLBAR_HSEP]:
toolBarItem.attrDict["icon"] = self.loadBitmap(basePathName, toolBarItem.attrDict["icon"]) toolBarItem.attrDict["icon"] = self.loadBitmap(basePathName, toolBarItem.attrDict["icon"])
# }}}
# {{{ onChar(self, event)
def onChar(self, event): def onChar(self, event):
self.canvasPanel.onKeyboardInput(event) self.canvasPanel.onKeyboardInput(event)
# }}}
# {{{ onMouseWheel(self, event)
def onMouseWheel(self, event): def onMouseWheel(self, event):
self.canvasPanel.GetEventHandler().ProcessEvent(event) self.canvasPanel.GetEventHandler().ProcessEvent(event)
# }}}
# #
# __init__(self, parent, defaultCanvasPos=(0, 75), defaultCanvasSize=(100, 30), defaultCellSize=(7, 14), size=(840, 630), title=""): initialisation method # __init__(self, parent, defaultCanvasPos=(0, 75), defaultCanvasSize=(100, 30), defaultCellSize=(7, 14), size=(840, 630), title=""): initialisation method
@ -43,7 +39,7 @@ class RoarClient(GuiFrame):
super().__init__(self._getIconPathName(), size, parent, title) super().__init__(self._getIconPathName(), size, parent, title)
self.canvas = Canvas(defaultCanvasSize) self.canvas = Canvas(defaultCanvasSize)
self.canvasPanel = RoarCanvasWindow(GuiCanvasWxBackend, self.canvas, defaultCellSize, RoarCanvasCommands, self.panelSkin, self, defaultCanvasPos, defaultCellSize, defaultCanvasSize) self.canvasPanel = RoarCanvasWindow(GuiCanvasWxBackend, self.canvas, defaultCellSize, RoarCanvasCommands, self.panelSkin, self, defaultCanvasPos, defaultCellSize, defaultCanvasSize)
self.loadAccels(self.canvasPanel.commands.menus, self.canvasPanel.commands.toolBars) self.loadAccels(self.canvasPanel.commands.accels, self.canvasPanel.commands.menus, self.canvasPanel.commands.toolBars)
self.loadMenus(self.canvasPanel.commands.menus) self.loadMenus(self.canvasPanel.commands.menus)
self._initToolBitmaps(self.canvasPanel.commands.toolBars) self._initToolBitmaps(self.canvasPanel.commands.toolBars)
self.loadToolBars(self.canvasPanel.commands.toolBars) self.loadToolBars(self.canvasPanel.commands.toolBars)

View File

@ -8,10 +8,9 @@ from glob import glob
import os, random, wx, wx.adv import os, random, wx, wx.adv
class RoarWindowAbout(wx.Dialog): class RoarWindowAbout(wx.Dialog):
# {{{ onButtonRoar(self, event)
def onButtonRoar(self, event): def onButtonRoar(self, event):
self.Destroy() self.Destroy()
# }}}
# #
# __init__(self, parent, minSize=(320, 300), title="About roar") # __init__(self, parent, minSize=(320, 300), title="About roar")

View File

@ -11,13 +11,11 @@ import select, socket, time
class IrcClient: class IrcClient:
"""Non-blocking abstraction over the IRC protocol""" """Non-blocking abstraction over the IRC protocol"""
# {{{ close(self): Close connection to server
def close(self): def close(self):
if self.clientSocket != None: if self.clientSocket != None:
self.clientSocket.close() self.clientSocket.close()
self.clientSocket = self.clientSocketFile = None; self.clientSocket = self.clientSocketFile = None;
# }}}
# {{{ connect(self, localAddr=None, preferFamily=socket.AF_INET, timeout=None): Connect to server and register w/ optional timeout
def connect(self, localAddr=None, preferFamily=socket.AF_INET, timeout=None): def connect(self, localAddr=None, preferFamily=socket.AF_INET, timeout=None):
gaiInfo = socket.getaddrinfo(self.serverHname, self.serverPort, gaiInfo = socket.getaddrinfo(self.serverHname, self.serverPort,
preferFamily, socket.SOCK_STREAM, socket.IPPROTO_TCP) preferFamily, socket.SOCK_STREAM, socket.IPPROTO_TCP)
@ -41,8 +39,7 @@ class IrcClient:
self.queue("NICK", self.clientNick) self.queue("NICK", self.clientNick)
self.queue("USER", self.clientIdent, "0", "0", self.clientGecos) self.queue("USER", self.clientIdent, "0", "0", self.clientGecos)
return True return True
# }}}
# {{{ queue(self, *args): Parse and queue single line to server from list
def queue(self, *args): def queue(self, *args):
msg = ""; argNumMax = len(args); msg = ""; argNumMax = len(args);
for argNum in range(argNumMax): for argNum in range(argNumMax):
@ -51,8 +48,7 @@ class IrcClient:
else: else:
msg += args[argNum] + " " msg += args[argNum] + " "
self.clientQueue.append((msg + "\r\n").encode()) self.clientQueue.append((msg + "\r\n").encode())
# }}}
# {{{ readline(self, timeout=30): Read and parse single line from server into canonicalised list, honouring timers
def readline(self, timeout=30): def readline(self, timeout=30):
if self.clientNextTimeout: if self.clientNextTimeout:
timeNow = time.time() timeNow = time.time()
@ -85,8 +81,7 @@ class IrcClient:
else: else:
msg = [""] + msg[0:] msg = [""] + msg[0:]
return msg return msg
# }}}
# {{{ unqueue(self, timeout=15): Send all queued lines to server, honouring timers
def unqueue(self, timeout=15): def unqueue(self, timeout=15):
while self.clientQueue: while self.clientQueue:
msg = self.clientQueue[0]; msgLen = len(msg); msgBytesSent = 0; msg = self.clientQueue[0]; msgLen = len(msg); msgBytesSent = 0;
@ -111,7 +106,7 @@ class IrcClient:
msg = msg[msgBytesSent:]; msgLen -= msgBytesSent; msg = msg[msgBytesSent:]; msgLen -= msgBytesSent;
del self.clientQueue[0] del self.clientQueue[0]
return True return True
# }}}
# #
# __init__(self, serverHname, serverPort, clientNick, clientIdent, clientGecos): initialisation method # __init__(self, serverHname, serverPort, clientNick, clientIdent, clientGecos): initialisation method

View File

@ -7,10 +7,9 @@
import os, platform import os, platform
# {{{ getLocalConfPathName(*args)
def getLocalConfPathName(*args): def getLocalConfPathName(*args):
vname = "LOCALAPPDATA" if platform.system() == "Windows" else "HOME" vname = "LOCALAPPDATA" if platform.system() == "Windows" else "HOME"
return os.path.join(os.getenv(vname), "roar", *args) return os.path.join(os.getenv(vname), "roar", *args)
# }}}
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 # vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -5,13 +5,11 @@
# #
class Tool(object): class Tool(object):
# {{{ onKeyboardEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyChar, keyCode, keyModifiers, mapPoint)
def onKeyboardEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyChar, keyCode, keyModifiers, mapPoint): def onKeyboardEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyChar, keyCode, keyModifiers, mapPoint):
return False, False return False, False
# }}}
# {{{ onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, dispatchFn, eventDc, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown)
def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown): def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown):
return False, False return False, False
# }}}
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 # vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -12,28 +12,43 @@ class ToolCircle(Tool):
# #
# onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown) # onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown)
def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown): def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown):
brushColours, dirty = brushColours.copy(), False brushColours, brushSize, dirty = list(brushColours), [brushSize[0] * 2, brushSize[1]], False
if mouseLeftDown: originPoint, radius = (brushSize[0] / 2, brushSize[0] / 2), brushSize[0]
brushColours[1] = brushColours[0] if mouseRightDown:
elif mouseRightDown: brushColours = [brushColours[1], brushColours[0]]
brushColours[0] = brushColours[1] cells = []
else:
brushColours[1] = brushColours[0]
_brushSize = brushSize[0] * 2
originPoint, radius = (_brushSize / 2, _brushSize / 2), _brushSize
for brushY in range(-radius, radius + 1): for brushY in range(-radius, radius + 1):
cells += [[]]
for brushX in range(-radius, radius + 1): for brushX in range(-radius, radius + 1):
if ((brushX ** 2) + (brushY ** 2) < (((radius ** 2) + radius) * 0.8)): if ((brushX ** 2) + (brushY ** 2) < (((radius ** 2) + radius) * 0.8)):
patch = [ \ cells[-1] += [[mapPoint[i] + int(originPoint[i] + o) for i, o in zip((0, 1,), (brushX, brushY,))]]
mapPoint[0] + int(originPoint[0] + brushX), \ if cells[-1] == []:
mapPoint[1] + int(originPoint[1] + brushY), \ del cells[-1]
*brushColours, 0, " "] for numRow in range(len(cells)):
if mouseLeftDown or mouseRightDown: for numCol in range(len(cells[numRow])):
if not dirty: if ((numRow == 0) or (numRow == (len(cells) - 1))) \
dirty = True or ((numCol == 0) or (numCol == (len(cells[numRow]) - 1))):
dispatchFn(eventDc, False, patch); dispatchFn(eventDc, True, patch); patch = [*cells[numRow][numCol], brushColours[0], brushColours[0], 0, " "]
elif ((numRow > 0) and (cells[numRow][numCol][0] < cells[numRow - 1][0][0])) \
or ((numRow < len(cells)) and (cells[numRow][numCol][0] < cells[numRow + 1][0][0])):
patch = [*cells[numRow][numCol], brushColours[0], brushColours[0], 0, " "]
elif ((numRow > 0) and (cells[numRow][numCol][0] > cells[numRow - 1][-1][0])) \
or ((numRow < len(cells)) and (cells[numRow][numCol][0] > cells[numRow + 1][-1][0])):
patch = [*cells[numRow][numCol], brushColours[0], brushColours[0], 0, " "]
elif brushColours[1] == -1:
if (cells[numRow][numCol][0] < canvas.size[0]) \
and (cells[numRow][numCol][1] < canvas.size[1]):
patch = [cells[numRow][numCol][0], cells[numRow][numCol][1], *canvas.map[cells[numRow][numCol][1]][cells[numRow][numCol][0]]]
else: else:
dispatchFn(eventDc, True, patch) patch = [*cells[numRow][numCol], brushColours[1], brushColours[1], 0, " "]
else:
patch = [*cells[numRow][numCol], brushColours[1], brushColours[1], 0, " "]
if mouseLeftDown or mouseRightDown:
if not dirty:
dirty = True
dispatchFn(eventDc, False, patch); dispatchFn(eventDc, True, patch);
else:
dispatchFn(eventDc, True, patch)
return True, dirty return True, dirty
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 # vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -5,6 +5,7 @@
# #
from Tool import Tool from Tool import Tool
import wx
class ToolFill(Tool): class ToolFill(Tool):
name = "Fill" name = "Fill"
@ -14,15 +15,19 @@ class ToolFill(Tool):
def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown): def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown):
dirty, pointsDone, pointStack, testChar, testColour = False, [], [list(mapPoint)], canvas.map[mapPoint[1]][mapPoint[0]][3], canvas.map[mapPoint[1]][mapPoint[0]][0:2] dirty, pointsDone, pointStack, testChar, testColour = False, [], [list(mapPoint)], canvas.map[mapPoint[1]][mapPoint[0]][3], canvas.map[mapPoint[1]][mapPoint[0]][0:2]
if mouseLeftDown or mouseRightDown: if mouseLeftDown or mouseRightDown:
if mouseLeftDown:
fillColour = brushColours[0]
else:
fillColour = brushColours[1]
while len(pointStack) > 0: while len(pointStack) > 0:
point = pointStack.pop() point = pointStack.pop()
pointCell = canvas.map[point[1]][point[0]] pointCell = canvas.map[point[1]][point[0]]
if ((pointCell[1] == testColour[1]) and ((pointCell[3] == testChar) or mouseRightDown)) \ if ((pointCell[1] == testColour[1]) and ((pointCell[3] == testChar) or (keyModifiers == wx.MOD_CONTROL))) \
or ((pointCell[3] == " ") and (pointCell[1] == testColour[1])): or ((pointCell[3] == " ") and (pointCell[1] == testColour[1])):
if not point in pointsDone: if not point in pointsDone:
if not dirty: if not dirty:
dirty = True dirty = True
dispatchFn(eventDc, False, [*point, brushColours[0], brushColours[0], 0, " "]) dispatchFn(eventDc, False, [*point, fillColour, fillColour, 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] < (canvas.size[0] - 1): if point[0] < (canvas.size[0] - 1):

View File

@ -11,7 +11,6 @@ class ToolLine(Tool):
TS_NONE = 0 TS_NONE = 0
TS_ORIGIN = 1 TS_ORIGIN = 1
# {{{ _getLine(self, brushColours, brushSize, dispatchFn, eventDc, isCursor, originPoint, targetPoint)
def _getLine(self, brushColours, brushSize, dispatchFn, eventDc, isCursor, originPoint, targetPoint): def _getLine(self, brushColours, brushSize, dispatchFn, eventDc, isCursor, originPoint, targetPoint):
dirty = False dirty = False
originPoint, targetPoint = originPoint.copy(), targetPoint.copy() originPoint, targetPoint = originPoint.copy(), targetPoint.copy()
@ -40,15 +39,13 @@ class ToolLine(Tool):
lineD -= pointDelta[0]; lineY += 1; lineD -= pointDelta[0]; lineY += 1;
lineD += pointDelta[1] lineD += pointDelta[1]
return dirty return dirty
# }}}
# {{{ _pointDelta(self, a, b)
def _pointDelta(self, a, b): def _pointDelta(self, a, b):
return [a2 - a1 for a1, a2 in zip(a, b)] return [a2 - a1 for a1, a2 in zip(a, b)]
# }}}
# {{{ _pointSwap(self, a, b)
def _pointSwap(self, a, b): def _pointSwap(self, a, b):
return [b, a] return [b, a]
# }}}
# #
# onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown) # onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown)

View File

@ -14,7 +14,6 @@ class ToolObject(Tool):
TS_SELECT = 2 TS_SELECT = 2
TS_TARGET = 3 TS_TARGET = 3
# {{{ _dispatchSelectEvent(self, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseLeftDown, selectRect)
def _dispatchSelectEvent(self, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseLeftDown, selectRect): def _dispatchSelectEvent(self, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseLeftDown, selectRect):
if mouseLeftDown: if mouseLeftDown:
disp, isCursor = [mapPoint[m] - self.lastAtPoint[m] for m in [0, 1]], True disp, isCursor = [mapPoint[m] - self.lastAtPoint[m] for m in [0, 1]], True
@ -26,8 +25,7 @@ class ToolObject(Tool):
self._drawSelectRect(newTargetRect, dispatchFn, eventDc) self._drawSelectRect(newTargetRect, dispatchFn, eventDc)
self.targetRect = newTargetRect self.targetRect = newTargetRect
return dirty return dirty
# }}}
# {{{ _drawSelectRect(self, rect, dispatchFn, eventDc)
def _drawSelectRect(self, rect, dispatchFn, eventDc): def _drawSelectRect(self, rect, dispatchFn, eventDc):
rectFrame = [[rect[m][n] for n in [0, 1]] for m in (0, 1)] rectFrame = [[rect[m][n] for n in [0, 1]] for m in (0, 1)]
if rectFrame[0][0] > rectFrame[1][0]: if rectFrame[0][0] > rectFrame[1][0]:
@ -43,8 +41,7 @@ class ToolObject(Tool):
curColours = [1, 1] if curColours == [0, 0] else [0, 0] curColours = [1, 1] if curColours == [0, 0] else [0, 0]
dispatchFn(eventDc, True, [rectFrame[0][0], rectY, *curColours, 0, " "]) dispatchFn(eventDc, True, [rectFrame[0][0], rectY, *curColours, 0, " "])
dispatchFn(eventDc, True, [rectFrame[1][0], rectY, *curColours, 0, " "]) dispatchFn(eventDc, True, [rectFrame[1][0], rectY, *curColours, 0, " "])
# }}}
# {{{ _mouseEventTsNone(self, brushColours, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown)
def _mouseEventTsNone(self, brushColours, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown): def _mouseEventTsNone(self, brushColours, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown):
self.substract = False self.substract = False
if self.external: if self.external:
@ -55,11 +52,10 @@ class ToolObject(Tool):
else: else:
dispatchFn(eventDc, True, [*mapPoint, *brushColours, 0, " "]) dispatchFn(eventDc, True, [*mapPoint, *brushColours, 0, " "])
return False return False
# }}}
# {{{ _mouseEventTsOrigin(self, brushColours, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown)
def _mouseEventTsOrigin(self, brushColours, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown): def _mouseEventTsOrigin(self, brushColours, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown):
self.targetRect[1] = list(mapPoint) self.targetRect[1] = list(mapPoint)
if mouseLeftDown: if not mouseLeftDown:
if self.targetRect[0][0] > self.targetRect[1][0]: if self.targetRect[0][0] > self.targetRect[1][0]:
self.targetRect[0][0], self.targetRect[1][0] = self.targetRect[1][0], self.targetRect[0][0] self.targetRect[0][0], self.targetRect[1][0] = self.targetRect[1][0], self.targetRect[0][0]
if self.targetRect[0][1] > self.targetRect[1][1]: if self.targetRect[0][1] > self.targetRect[1][1]:
@ -74,8 +70,7 @@ class ToolObject(Tool):
else: else:
self._drawSelectRect(self.targetRect, dispatchFn, eventDc) self._drawSelectRect(self.targetRect, dispatchFn, eventDc)
return False return False
# }}}
# {{{ _mouseEventTsSelect(self, brushColours, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown)
def _mouseEventTsSelect(self, brushColours, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown): def _mouseEventTsSelect(self, brushColours, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown):
dirty = False dirty = False
if mouseLeftDown: if mouseLeftDown:
@ -91,8 +86,7 @@ class ToolObject(Tool):
else: else:
dirty = self._dispatchSelectEvent(canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseLeftDown, self.targetRect) dirty = self._dispatchSelectEvent(canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseLeftDown, self.targetRect)
return dirty return dirty
# }}}
# {{{ _mouseEventTsTarget(self, brushColours, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown)
def _mouseEventTsTarget(self, brushColours, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown): def _mouseEventTsTarget(self, brushColours, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown):
if (keyModifiers == wx.MOD_CONTROL) and (self.srcRect == self.targetRect): if (keyModifiers == wx.MOD_CONTROL) and (self.srcRect == self.targetRect):
self.substract = True self.substract = True
@ -102,13 +96,11 @@ class ToolObject(Tool):
else: else:
self.toolState = self.TS_SELECT self.toolState = self.TS_SELECT
return dirty return dirty
# }}}
# {{{ getRegion(self, canvas)
def getRegion(self, canvas): def getRegion(self, canvas):
return self.objectMap return self.objectMap
# }}}
# {{{ onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown)
def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown): def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown):
dirty = False dirty = False
if self.toolState == self.TS_NONE: if self.toolState == self.TS_NONE:
@ -122,8 +114,7 @@ class ToolObject(Tool):
else: else:
return False, dirty return False, dirty
return True, dirty return True, dirty
# }}}
# {{{ onSelectEvent(self, canvas, disp, dispatchFn, eventDc, isCursor, keyModifiers, newTargetRect, selectRect)
def onSelectEvent(self, canvas, disp, dispatchFn, eventDc, isCursor, keyModifiers, newTargetRect, selectRect): def onSelectEvent(self, canvas, disp, dispatchFn, eventDc, isCursor, keyModifiers, newTargetRect, selectRect):
dirty = False dirty = False
if self.external: if self.external:
@ -149,10 +140,13 @@ class ToolObject(Tool):
cellOld = self.objectMap[numRow][numCol] cellOld = self.objectMap[numRow][numCol]
rectX, rectY = selectRect[0][0] + numCol, selectRect[0][1] + numRow rectX, rectY = selectRect[0][0] + numCol, selectRect[0][1] + numRow
dirty = False if isCursor else True dirty = False if isCursor else True
dispatchFn(eventDc, isCursor, [rectX + disp[0], rectY + disp[1], *cellOld]) cellNew = self.objectMap[numRow][numCol]
if (cellNew[1] == -1) and (cellNew[3] == " "):
if ((rectY + disp[1]) < canvas.size[1]) and ((rectX + disp[0]) < canvas.size[0]):
cellNew = canvas.map[rectY + disp[1]][rectX + disp[0]]
dispatchFn(eventDc, isCursor, [rectX + disp[0], rectY + disp[1], *cellNew])
return dirty return dirty
# }}}
# {{{ setRegion(self, canvas, mapPoint, objectMap, objectSize, external=True)
def setRegion(self, canvas, mapPoint, objectMap, objectSize, external=True): def setRegion(self, canvas, mapPoint, objectMap, objectSize, external=True):
self.external, self.toolState = external, self.TS_SELECT self.external, self.toolState = external, self.TS_SELECT
if mapPoint != None: if mapPoint != None:
@ -166,7 +160,7 @@ class ToolObject(Tool):
if self.srcRect == None: if self.srcRect == None:
self.srcRect = self.targetRect self.srcRect = self.targetRect
self.objectMap, self.objectSize = objectMap, objectSize self.objectMap, self.objectSize = objectMap, objectSize
# }}}
# __init__(self, *args): initialisation method # __init__(self, *args): initialisation method
def __init__(self, *args): def __init__(self, *args):

View File

@ -12,19 +12,26 @@ class ToolRect(Tool):
# #
# onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown) # onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown)
def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown): def onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown):
brushColours, dirty = brushColours.copy(), False brushColours, brushSize, dirty = list(brushColours), list(brushSize), False
if mouseLeftDown: if mouseRightDown:
brushColours[1] = brushColours[0] brushColours = [brushColours[1], brushColours[0]]
elif mouseRightDown:
brushColours[0] = brushColours[1]
else:
brushColours[1] = brushColours[0]
brushSize = brushSize.copy()
if brushSize[0] > 1: if brushSize[0] > 1:
brushSize[0] *= 2 brushSize[0] *= 2
for brushRow in range(brushSize[1]): for brushRow in range(brushSize[1]):
for brushCol in range(brushSize[0]): for brushCol in range(brushSize[0]):
patch = [mapPoint[0] + brushCol, mapPoint[1] + brushRow, *brushColours, 0, " "] if (brushCol in [0, brushSize[0] - 1]) \
or (brushRow in [0, brushSize[1] - 1]):
patchColours = [brushColours[0]] * 2
patch = [mapPoint[0] + brushCol, mapPoint[1] + brushRow, *patchColours, 0, " "]
elif brushColours[1] == -1:
if ((mapPoint[0] + brushCol) < canvas.size[0]) \
and ((mapPoint[1] + brushRow) < canvas.size[1]):
patch = [mapPoint[0] + brushCol, mapPoint[1] + brushRow, *canvas.map[mapPoint[1] + brushRow][mapPoint[0] + brushCol]]
else:
patch = [mapPoint[0] + brushCol, mapPoint[1] + brushRow, -1, -1, 0, " "]
else:
patchColours = [brushColours[1]] * 2
patch = [mapPoint[0] + brushCol, mapPoint[1] + brushRow, *patchColours, 0, " "]
if mouseLeftDown or mouseRightDown: if mouseLeftDown or mouseRightDown:
if not dirty: if not dirty:
dirty = True dirty = True

View File

@ -13,7 +13,6 @@ class ToolText(Tool):
arabicRegEx = r'^[\u0621-\u063A\u0640-\u064A]+$' arabicRegEx = r'^[\u0621-\u063A\u0640-\u064A]+$'
rtlRegEx = r'^[\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC]+$' rtlRegEx = r'^[\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC]+$'
# {{{ _checkRtl(self, canvas, brushPos, keyChar)
def _checkRtl(self, canvas, brushPos, keyChar): def _checkRtl(self, canvas, brushPos, keyChar):
rtlFlag = False rtlFlag = False
if (keyChar != None) and re.match(self.rtlRegEx, keyChar): if (keyChar != None) and re.match(self.rtlRegEx, keyChar):
@ -41,13 +40,11 @@ class ToolText(Tool):
else: else:
break break
return rtlFlag return rtlFlag
# }}}
# {{{ _processKeyChar(self, brushColours, brushPos, canvas, dispatchFn, eventDc, keyChar, keyModifiers)
def _processKeyChar(self, brushColours, brushPos, canvas, dispatchFn, eventDc, keyChar, keyModifiers): def _processKeyChar(self, brushColours, brushPos, canvas, dispatchFn, eventDc, keyChar, keyModifiers):
if (ord(keyChar) != wx.WXK_NONE) \ if (ord(keyChar) != wx.WXK_NONE) \
and (not keyChar in set("\t\n\v\f\r")) \ and (not keyChar in set("\t\n\v\f\r")) \
and ((ord(keyChar) >= 32) if ord(keyChar) < 127 else True) \ and ((ord(keyChar) >= 32) if ord(keyChar) < 127 else True):
and (keyModifiers in (wx.MOD_NONE, wx.MOD_SHIFT)):
dispatchFn(eventDc, False, [*brushPos, *brushColours, 0, keyChar]); dispatchFn(eventDc, False, [*brushPos, *brushColours, 0, keyChar]);
if not self._checkRtl(canvas, brushPos, keyChar): if not self._checkRtl(canvas, brushPos, keyChar):
if brushPos[0] < (canvas.size[0] - 1): if brushPos[0] < (canvas.size[0] - 1):
@ -67,7 +64,7 @@ class ToolText(Tool):
else: else:
rc, dirty = False, False rc, dirty = False, False
return rc, dirty return rc, dirty
# }}}
# #
# onKeyboardEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyChar, keyCode, keyModifiers, mapPoint) # onKeyboardEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyChar, keyCode, keyModifiers, mapPoint)

View File

@ -1 +0,0 @@
.

1
requirements.txt Symbolic link
View File

@ -0,0 +1 @@
assets/text/requirements.txt