mirror of
https://github.com/lalbornoz/roar.git
synced 2024-11-22 15:26:37 +00:00
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:
parent
14d3560b70
commit
ced45fa0d4
BIN
assets/audio/roararab8.wav
Normal file
BIN
assets/audio/roararab8.wav
Normal file
Binary file not shown.
BIN
assets/audio/roarspoke11.wav
Normal file
BIN
assets/audio/roarspoke11.wav
Normal file
Binary file not shown.
BIN
assets/images/toolColoursFlip.png
Normal file
BIN
assets/images/toolColoursFlip.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 221 B |
BIN
assets/images/toolHideAssetsWindow.png
Normal file
BIN
assets/images/toolHideAssetsWindow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 274 B |
BIN
assets/images/toolShowAssetsWindow.png
Normal file
BIN
assets/images/toolShowAssetsWindow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 268 B |
@ -1,26 +1,29 @@
|
||||
Low-priority list:
|
||||
1) Implement ANSI CSI CU[BDPU] sequences & italic
|
||||
2) Layers & layout (e.g. for comics, zines, etc.)
|
||||
3) Implement instrumentation & unit tests, document
|
||||
4) Open and toggle a reference image in the background
|
||||
5) Client-Server or Peer-to-Peer realtime collaboration
|
||||
6) Arbitrary {format,palette}s ({4,8} bit ANSI/mIRC, etc.)
|
||||
7) {record,replay} {keyboard,mouse,...} events in debugging builds
|
||||
8) Incremental auto{load,save} & {backup,restore} (needs Settings window)
|
||||
9) Composition, parametrisation & keying of tools from higher-order operators (brushes, functions, filters, outlines, patterns & shaders) and unit tools
|
||||
10) Sprites & scripted (Python?) animation on the basis of asset traits and {composable,parametrised} patterns (metric flow, particle system, rigging, ...)
|
||||
11) Integrate ENNTool code in the form of OpenGL-based animation window (see 9) and 10))
|
||||
|
||||
High-priority list:
|
||||
1) unit tools: arrow, {cloud,speech bubble}, curve, measure, pick, polygon, triangle, unicode
|
||||
2) operators: rotate, scale, shift, slice, tile
|
||||
3) cleanup & refactor, switch to GTK
|
||||
4) GUI:
|
||||
1) Finish Arabic/RTL text tool support
|
||||
2) ANSI CSI CU[BDPU] sequences & italic
|
||||
3) Operators: crop, scale, shift, slice
|
||||
4) Documentation, instrumentation & unit tests
|
||||
5) Layers & layout (e.g. for comics, zines, etc.)
|
||||
6) Open and toggle a reference image in the background
|
||||
7) Client-Server or Peer-to-Peer realtime collaboration
|
||||
8) Arbitrary {format,palette}s ({4,8} bit ANSI/mIRC, etc.)
|
||||
9) {record,replay} {keyboard,mouse,...} events in debugging builds
|
||||
10) Incremental auto{load,save} & {backup,restore} (needs Settings window)
|
||||
11) Unit tools: arrow, {cloud,speech bubble}, curve, measure, polygon, triangle
|
||||
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
|
||||
14) Sprites & scripted (Python?) animation on the basis of asset traits and {composable,parametrised} patterns (metric flow, particle system, rigging, ...)
|
||||
15) GUI TODO list:
|
||||
a) replace logo w/ canvas panel in About dialogue
|
||||
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, ...)
|
||||
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}}
|
||||
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
|
||||
|
15
assets/text/hotkeys.txt
Normal file
15
assets/text/hotkeys.txt
Normal 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
|
1
assets/text/requirements.txt
Normal file
1
assets/text/requirements.txt
Normal file
@ -0,0 +1 @@
|
||||
.
|
@ -19,17 +19,14 @@ class IrcMiRCARTBot(IrcClient):
|
||||
"""IRC<->MiRC2png bot"""
|
||||
imgurApiKey = ImgurApiKey.imgurApiKey
|
||||
|
||||
# {{{ ContentTooLargeException(Exception): Raised by _urlretrieveReportHook() given download size > 1 MB
|
||||
class ContentTooLargeException(Exception):
|
||||
pass
|
||||
# }}}
|
||||
# {{{ _dispatch001(self, message): Dispatch single 001 (RPL_WELCOME)
|
||||
|
||||
def _dispatch001(self, message):
|
||||
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.queue("JOIN", self.clientChannel)
|
||||
# }}}
|
||||
# {{{ _dispatch353(self, message): Dispatch single 353 (RPL_NAMREPLY)
|
||||
|
||||
def _dispatch353(self, message):
|
||||
if message[4].lower() == self.clientChannel.lower():
|
||||
for channelNickSpec in message[5].split(" "):
|
||||
@ -38,20 +35,17 @@ class IrcMiRCARTBot(IrcClient):
|
||||
and len(channelNickSpec[1:]):
|
||||
self.clientChannelOps.append(channelNickSpec[1:].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):
|
||||
self._log("Joined {} on {}:{}.".format(message[2].lower(), self.serverHname, self.serverPort))
|
||||
self.clientNextTimeout = None; self.clientChannelRejoin = False;
|
||||
# }}}
|
||||
# {{{ _dispatchKick(self, message): Dispatch single KICK message from server
|
||||
|
||||
def _dispatchKick(self, message):
|
||||
if message[2].lower() == self.clientChannel.lower() \
|
||||
and message[3].lower() == self.clientNick.lower():
|
||||
self._log("Kicked from {} by {}, rejoining in 15 seconds".format(message[2].lower(), message[0]))
|
||||
self.clientNextTimeout = time.time() + 15; self.clientChannelRejoin = True;
|
||||
# }}}
|
||||
# {{{ _dispatchMode(self, message): Dispatch single MODE message from server
|
||||
|
||||
def _dispatchMode(self, message):
|
||||
if message[2].lower() == self.clientChannel.lower():
|
||||
channelModeType = "+"; channelModeArg = 4;
|
||||
@ -78,17 +72,14 @@ class IrcMiRCARTBot(IrcClient):
|
||||
channelAuthDel = channelAuthDel.lower()
|
||||
self._log("Deauthorising {} on {}".format(channelAuthDel, message[2].lower()))
|
||||
self.clientChannelOps.remove(channelAuthDel)
|
||||
# }}}
|
||||
# {{{ _dispatchNone(self): Dispatch None message from server
|
||||
|
||||
def _dispatchNone(self):
|
||||
self._log("Disconnected from {}:{}.".format(self.serverHname, self.serverPort))
|
||||
self.close()
|
||||
# }}}
|
||||
# {{{ _dispatchPing(self, message): Dispatch single PING message from server
|
||||
|
||||
def _dispatchPing(self, message):
|
||||
self.queue("PONG", message[2])
|
||||
# }}}
|
||||
# {{{ _dispatchPrivmsg(self, message): Dispatch single PRIVMSG message from server
|
||||
|
||||
def _dispatchPrivmsg(self, message):
|
||||
if message[2].lower() == self.clientChannel.lower() \
|
||||
and message[3].startswith("!pngbot "):
|
||||
@ -155,19 +146,16 @@ class IrcMiRCARTBot(IrcClient):
|
||||
os.remove(asciiTmpFilePath)
|
||||
if os.path.isfile(imgTmpFilePath):
|
||||
os.remove(imgTmpFilePath)
|
||||
# }}}
|
||||
# {{{ _dispatchTimer(self): Dispatch single client timer expiration
|
||||
|
||||
def _dispatchTimer(self):
|
||||
if self.clientChannelRejoin:
|
||||
self._log("Attempting to join {} on {}:{}...".format(self.clientChannel, self.serverHname, self.serverPort))
|
||||
self.queue("JOIN", self.clientChannel)
|
||||
self.clientNextTimeout = time.time() + 15; self.clientChannelRejoin = True;
|
||||
# }}}
|
||||
# {{{ _log(self, msg): Log single message to stdout w/ timestamp
|
||||
|
||||
def _log(self, 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):
|
||||
with open(imgFilePath, "rb") as requestImage:
|
||||
requestImageData = requestImage.read()
|
||||
@ -188,13 +176,11 @@ class IrcMiRCARTBot(IrcClient):
|
||||
return [200, responseDict.get("data").get("link")]
|
||||
else:
|
||||
return [responseHttp.status_code, responseHttp.text]
|
||||
# }}}
|
||||
# {{{ _urlretrieveReportHook(count, blockSize, totalSize): Limit downloads to 1 MB
|
||||
|
||||
def _urlretrieveReportHook(count, blockSize, totalSize):
|
||||
if (totalSize > pow(2,20)):
|
||||
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):
|
||||
self._log("Connecting to {}:{}...".format(self.serverHname, self.serverPort))
|
||||
if super().connect(localAddr=localAddr, preferFamily=preferFamily, timeout=timeout):
|
||||
@ -206,8 +192,7 @@ class IrcMiRCARTBot(IrcClient):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
# }}}
|
||||
# {{{ dispatch(self): Read, parse, and dispatch single line from server
|
||||
|
||||
def dispatch(self):
|
||||
while True:
|
||||
if self.clientNextTimeout:
|
||||
@ -245,7 +230,7 @@ class IrcMiRCARTBot(IrcClient):
|
||||
self.clientHasPing = False
|
||||
elif serverMessage[1] == "PRIVMSG":
|
||||
self._dispatchPrivmsg(serverMessage)
|
||||
# }}}
|
||||
|
||||
|
||||
#
|
||||
# __init__(self, serverHname, serverPort="6667", clientNick="pngbot", clientIdent="pngbot", clientGecos="pngbot", clientChannel="#MiRCART"): initialisation method
|
||||
|
@ -9,12 +9,10 @@ from CanvasImportStore import CanvasImportStore
|
||||
from CanvasJournal import CanvasJournal
|
||||
|
||||
class Canvas():
|
||||
# {{{ _commitPatch(self, patch)
|
||||
def _commitPatch(self, patch):
|
||||
self.map[patch[1]][patch[0]] = patch[2:]
|
||||
# }}}
|
||||
|
||||
# {{{ 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]):
|
||||
return False
|
||||
@ -27,8 +25,7 @@ class Canvas():
|
||||
self.journal.begin(); self.journal.updateCurrentDeltas(patch, patchDelta); self.journal.end();
|
||||
self._commitPatch(patch)
|
||||
return True
|
||||
# }}}
|
||||
# {{{ 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]):
|
||||
return False
|
||||
@ -41,8 +38,7 @@ class Canvas():
|
||||
self.journal.updateCurrentDeltas(patch, patchDelta)
|
||||
self._commitPatch(patch)
|
||||
return True
|
||||
# }}}
|
||||
# {{{ resize(self, newSize, commitUndo=True)
|
||||
|
||||
def resize(self, newSize, commitUndo=True):
|
||||
if newSize != self.size:
|
||||
if self.map == None:
|
||||
@ -87,8 +83,7 @@ class Canvas():
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
# }}}
|
||||
# {{{ update(self, newSize, newCanvas=None)
|
||||
|
||||
def update(self, newSize, newCanvas=None):
|
||||
for numRow in range(self.size[1]):
|
||||
for numCol in range(self.size[0]):
|
||||
@ -96,7 +91,7 @@ class Canvas():
|
||||
and (numRow < len(newCanvas)) \
|
||||
and (numCol < len(newCanvas[numRow])):
|
||||
self._commitPatch([numCol, numRow, *newCanvas[numRow][numCol]])
|
||||
# }}}
|
||||
|
||||
|
||||
#
|
||||
# __init__(self, size): initialisation method
|
||||
|
@ -4,7 +4,6 @@
|
||||
# Copyright (c) 2018, 2019 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
|
||||
#
|
||||
|
||||
# {{{ AnsiBgToMiRCARTColours
|
||||
AnsiBgToMiRCARTColours = {
|
||||
107: 0, # Bright White
|
||||
40: 1, # Black
|
||||
@ -23,8 +22,7 @@ AnsiBgToMiRCARTColours = {
|
||||
100: 14, # Grey
|
||||
47: 15, # Light Grey
|
||||
};
|
||||
# }}}
|
||||
# {{{ AnsiFgBoldToMiRCARTColours
|
||||
|
||||
AnsiFgBoldToMiRCARTColours = {
|
||||
97: 0, # Bright White
|
||||
30: 14, # Grey
|
||||
@ -43,8 +41,7 @@ AnsiFgBoldToMiRCARTColours = {
|
||||
90: 14, # Grey
|
||||
37: 0, # Bright White
|
||||
};
|
||||
# }}}
|
||||
# {{{ AnsiFgToMiRCARTColours
|
||||
|
||||
AnsiFgToMiRCARTColours = {
|
||||
97: 0, # Bright White
|
||||
30: 1, # Black
|
||||
@ -63,8 +60,7 @@ AnsiFgToMiRCARTColours = {
|
||||
90: 14, # Grey
|
||||
37: 15, # Light Grey
|
||||
};
|
||||
# }}}
|
||||
# {{{ ColourMapBold: mIRC colour number to RGBA map given ^B (bold)
|
||||
|
||||
ColourMapBold = [
|
||||
[255, 255, 255], # Bright White
|
||||
[85, 85, 85], # Black
|
||||
@ -83,8 +79,7 @@ ColourMapBold = [
|
||||
[85, 85, 85], # Grey
|
||||
[255, 255, 255], # Light Grey
|
||||
]
|
||||
# }}}
|
||||
# {{{ ColourMapNormal: mIRC colour number to RGBA map given none of ^[BFV_] (bold, italic, reverse, underline)
|
||||
|
||||
ColourMapNormal = [
|
||||
[255, 255, 255], # Bright White
|
||||
[0, 0, 0], # Black
|
||||
@ -103,8 +98,7 @@ ColourMapNormal = [
|
||||
[85, 85, 85], # Grey
|
||||
[187, 187, 187], # Light Grey
|
||||
]
|
||||
# }}}
|
||||
# {{{ MiRCARTToAnsiColours
|
||||
|
||||
MiRCARTToAnsiColours = [
|
||||
97, # Bright White
|
||||
30, # Black
|
||||
@ -123,6 +117,6 @@ MiRCARTToAnsiColours = [
|
||||
90, # Grey
|
||||
37, # Light Grey
|
||||
];
|
||||
# }}}
|
||||
|
||||
|
||||
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
||||
|
@ -20,25 +20,22 @@ except ImportError:
|
||||
haveUrllib = False
|
||||
|
||||
class CanvasExportStore():
|
||||
# {{{ _CellState(): Cell state
|
||||
class _CellState():
|
||||
CS_NONE = 0x00
|
||||
CS_BOLD = 0x01
|
||||
CS_ITALIC = 0x02
|
||||
CS_UNDERLINE = 0x04
|
||||
# }}}
|
||||
|
||||
ImgurUploadUrl = "https://api.imgur.com/3/upload.json"
|
||||
PastebinPostUrl = "https://pastebin.com/api/api_post.php"
|
||||
|
||||
# {{{ _drawUnderline(self, curPos, fillColour, fontSize, imgDraw)
|
||||
def _drawUnderLine(self, curPos, fillColour, fontSize, imgDraw):
|
||||
imgDraw.line( \
|
||||
xy=(curPos[0], curPos[1] + (fontSize[1] - 2), \
|
||||
curPos[0] + fontSize[0], curPos[1] + (fontSize[1] - 2)), \
|
||||
fill=fillColour)
|
||||
# }}}
|
||||
|
||||
# {{{ exportAnsiFile(self, canvasMap, canvasSize, outFile)
|
||||
|
||||
def exportAnsiFile(self, canvasMap, canvasSize, outFile):
|
||||
outBuffer = ""
|
||||
for inCurRow in range(len(canvasMap)):
|
||||
@ -71,8 +68,7 @@ class CanvasExportStore():
|
||||
return (True, None)
|
||||
else:
|
||||
return (False, "empty buffer generated")
|
||||
# }}}
|
||||
# {{{ exportBitmapToImgur(self, apiKey, canvasBitmap, imgName, imgTitle, imgType)
|
||||
|
||||
def exportBitmapToImgur(self, apiKey, canvasBitmap, imgName, imgTitle, imgType):
|
||||
tmpPathName = tempfile.mkstemp()
|
||||
os.close(tmpPathName[0])
|
||||
@ -94,12 +90,10 @@ class CanvasExportStore():
|
||||
imgurResult = (False, responseHttp.status_code, responseDict.get("data"))
|
||||
os.remove(tmpPathName[1])
|
||||
return imgurResult
|
||||
# }}}
|
||||
# {{{ exportBitmapToPngFile(self, canvasBitmap, outPathName, outType)
|
||||
|
||||
def exportBitmapToPngFile(self, canvasBitmap, 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):
|
||||
if haveUrllib:
|
||||
outFile = io.StringIO()
|
||||
@ -117,8 +111,7 @@ class CanvasExportStore():
|
||||
return (False, str(responseHttp.status_code))
|
||||
else:
|
||||
return (False, "missing requests and/or urllib3 module(s)")
|
||||
# }}}
|
||||
# {{{ exportPngFile(self, canvasMap, fontFilePath, fontSize, outPathName)
|
||||
|
||||
def exportPngFile(self, canvasMap, fontFilePath, fontSize, outPathName):
|
||||
if havePIL:
|
||||
inSize = (len(canvasMap[0]), len(canvasMap))
|
||||
@ -161,8 +154,7 @@ class CanvasExportStore():
|
||||
return (True, None)
|
||||
else:
|
||||
return (False, "missing PIL modules")
|
||||
# }}}
|
||||
# {{{ exportTextBuffer(self, canvasMap, canvasSize)
|
||||
|
||||
def exportTextBuffer(self, canvasMap, canvasSize):
|
||||
outBuffer = ""
|
||||
for canvasRow in range(canvasSize[1]):
|
||||
@ -213,11 +205,10 @@ class CanvasExportStore():
|
||||
return (True, outBuffer)
|
||||
else:
|
||||
return (False, "empty buffer generated")
|
||||
# }}}
|
||||
# {{{ exportTextFile(self, canvasMap, canvasSize, outFile)
|
||||
|
||||
def exportTextFile(self, canvasMap, canvasSize, outFile):
|
||||
rc, outBuffer = self.exportTextBuffer(canvasMap, canvasSize)
|
||||
return outFile.write(outBuffer) if rc else (rc, outBuffer)
|
||||
# }}}
|
||||
|
||||
|
||||
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
||||
|
@ -9,20 +9,17 @@ from CanvasColours import AnsiBgToMiRCARTColours, AnsiFgToMiRCARTColours, AnsiFg
|
||||
import io, os, re, struct, sys
|
||||
|
||||
class CanvasImportStore():
|
||||
# {{{ _CellState(): Cell state
|
||||
class _CellState():
|
||||
CS_NONE = 0x00
|
||||
CS_BOLD = 0x01
|
||||
CS_ITALIC = 0x02
|
||||
CS_UNDERLINE = 0x04
|
||||
# }}}
|
||||
|
||||
# {{{ _flipCellStateBit(self, bit, cellState)
|
||||
|
||||
def _flipCellStateBit(self, bit, cellState):
|
||||
return cellState & ~bit if cellState & bit else cellState | bit
|
||||
# }}}
|
||||
|
||||
# {{{ 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
|
||||
done, outMap, outMaxCols = False, [[]], 0
|
||||
@ -74,12 +71,10 @@ class CanvasImportStore():
|
||||
return (True, None)
|
||||
else:
|
||||
return (False, "empty output map")
|
||||
# }}}
|
||||
# {{{ importAnsiFile(self, inPathName, encoding="cp437")
|
||||
|
||||
def importAnsiFile(self, inPathName, encoding="cp437"):
|
||||
return self.importAnsiBuffer(open(inPathName, "rb").read(), encoding)
|
||||
# }}}
|
||||
# {{{ importSauceFile(self, inPathName, encoding="cp437")
|
||||
|
||||
def importSauceFile(self, inPathName, encoding="cp437"):
|
||||
with open(inPathName, "rb") as inFile:
|
||||
inFileStat = os.stat(inPathName)
|
||||
@ -90,8 +85,7 @@ class CanvasImportStore():
|
||||
return self.importAnsiBuffer(inFileData, encoding, width)
|
||||
else:
|
||||
return (False, "only character based ANSi SAUCE files are supported")
|
||||
# }}}
|
||||
# {{{ importTextBuffer(self, inFile)
|
||||
|
||||
def importTextBuffer(self, inFile):
|
||||
try:
|
||||
inLine, outMap, outMaxCols = inFile.readline(), [], 0
|
||||
@ -137,12 +131,11 @@ class CanvasImportStore():
|
||||
return (False, "empty output map")
|
||||
except:
|
||||
return (False, sys.exc_info()[1])
|
||||
# }}}
|
||||
# {{{ importTextFile(self, pathName)
|
||||
|
||||
def importTextFile(self, pathName):
|
||||
with open(pathName, "r", encoding="utf-8-sig") as inFile:
|
||||
return self.importTextBuffer(inFile)
|
||||
# }}}
|
||||
|
||||
|
||||
#
|
||||
# __init__(self, inFile=None): initialisation method
|
||||
|
@ -5,68 +5,58 @@
|
||||
#
|
||||
|
||||
class CanvasJournal():
|
||||
# {{{ begin(self)
|
||||
def begin(self):
|
||||
deltaItem = [[], []]; self.patchesUndo.insert(self.patchesUndoLevel, deltaItem);
|
||||
# }}}
|
||||
# {{{ end(self)
|
||||
|
||||
def end(self):
|
||||
if self.patchesUndo[self.patchesUndoLevel] == [[], []]:
|
||||
del self.patchesUndo[self.patchesUndoLevel]
|
||||
else:
|
||||
if self.patchesUndoLevel > 0:
|
||||
del self.patchesUndo[:self.patchesUndoLevel]; self.patchesUndoLevel = 0;
|
||||
# }}}
|
||||
# {{{ popCursor(self)
|
||||
|
||||
def popCursor(self):
|
||||
if len(self.patchesCursor):
|
||||
patchesCursor = self.patchesCursor; self.patchesCursor = [];
|
||||
return patchesCursor
|
||||
else:
|
||||
return []
|
||||
# }}}
|
||||
# {{{ popRedo(self)
|
||||
|
||||
def popRedo(self):
|
||||
if self.patchesUndoLevel > 0:
|
||||
self.patchesUndoLevel -= 1; patches = self.patchesUndo[self.patchesUndoLevel];
|
||||
return patches[1]
|
||||
else:
|
||||
return []
|
||||
# }}}
|
||||
# {{{ popUndo(self)
|
||||
|
||||
def popUndo(self):
|
||||
if self.patchesUndo[self.patchesUndoLevel] != None:
|
||||
patches = self.patchesUndo[self.patchesUndoLevel]; self.patchesUndoLevel += 1;
|
||||
return patches[0]
|
||||
else:
|
||||
return []
|
||||
# }}}
|
||||
# {{{ pushCursor(self, patches)
|
||||
|
||||
def pushCursor(self, patches):
|
||||
self.patchesCursor.append(patches)
|
||||
# }}}
|
||||
# {{{ resetCursor(self)
|
||||
|
||||
def resetCursor(self):
|
||||
if self.patchesCursor != None:
|
||||
self.patchesCursor.clear()
|
||||
self.patchesCursor = []
|
||||
# }}}
|
||||
# {{{ resetUndo(self)
|
||||
|
||||
def resetUndo(self):
|
||||
if self.patchesUndo != None:
|
||||
self.patchesUndo.clear()
|
||||
self.patchesUndo = [None]; self.patchesUndoLevel = 0;
|
||||
# }}}
|
||||
# {{{ updateCurrentDeltas(self, redoPatches, undoPatches)
|
||||
|
||||
def updateCurrentDeltas(self, redoPatches, undoPatches):
|
||||
self.patchesUndo[self.patchesUndoLevel][0].append(undoPatches)
|
||||
self.patchesUndo[self.patchesUndoLevel][1].append(redoPatches)
|
||||
# }}}
|
||||
|
||||
# {{{ __del__(self): destructor method
|
||||
|
||||
def __del__(self):
|
||||
self.resetCursor(); self.resetUndo();
|
||||
# }}}
|
||||
|
||||
|
||||
#
|
||||
# __init__(self): initialisation method
|
||||
|
@ -9,12 +9,10 @@ from GuiCanvasColours import Colours
|
||||
import math, os, platform, wx
|
||||
|
||||
class GuiBufferedDC(wx.MemoryDC):
|
||||
# {{{ __del__(self)
|
||||
def __del__(self):
|
||||
self.dc.Blit(0, 0, *self.viewSize, self, 0, 0)
|
||||
self.SelectObject(wx.NullBitmap)
|
||||
# }}}
|
||||
# {{{ __init__(self, backend, buffer, clientSize, dc, viewRect)
|
||||
|
||||
def __init__(self, backend, buffer, clientSize, dc, viewRect):
|
||||
super().__init__()
|
||||
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)]
|
||||
self.SelectObject(buffer); self.SetDeviceOrigin(*viewRect);
|
||||
self.dc, self.viewRect, self.viewSize = dc, viewRect, viewSize
|
||||
# }}}
|
||||
|
||||
|
||||
class GuiCanvasWxBackend():
|
||||
# {{{ arabicShapes{}
|
||||
arabicShapes = {
|
||||
u'\u0621': (u'\uFE80'),
|
||||
u'\u0622': (u'\uFE81', None, None, u'\uFE82'),
|
||||
@ -67,23 +64,20 @@ class GuiCanvasWxBackend():
|
||||
u'\u0649': (u'\uFEEF', None, None, u'\uFEF0'),
|
||||
u'\u064A': (u'\uFEF1', u'\uFEF3', u'\uFEF4', u'\uFEF2'),
|
||||
}
|
||||
# }}}
|
||||
# {{{ _CellState(): Cell state
|
||||
|
||||
class _CellState():
|
||||
CS_NONE = 0x00
|
||||
CS_BOLD = 0x01
|
||||
CS_ITALIC = 0x02
|
||||
CS_UNDERLINE = 0x04
|
||||
# }}}
|
||||
|
||||
# {{{ _drawBrushPatch(self, eventDc, patch, point)
|
||||
|
||||
def _drawBrushPatch(self, eventDc, patch, point):
|
||||
absPoint = self._xlatePoint(point)
|
||||
brushBg, brushFg, pen = self._getBrushPatchColours(patch)
|
||||
self._setBrushDc(brushBg, brushFg, eventDc, pen)
|
||||
eventDc.DrawRectangle(*absPoint, *self.cellSize)
|
||||
# }}}
|
||||
# {{{ _drawCharPatch(self, eventDc, patch, point)
|
||||
|
||||
def _drawCharPatch(self, eventDc, patch, point):
|
||||
absPoint, fontBitmap = self._xlatePoint(point), wx.Bitmap(*self.cellSize)
|
||||
brushBg, brushFg, pen = self._getCharPatchColours(patch)
|
||||
@ -99,14 +93,12 @@ class GuiCanvasWxBackend():
|
||||
if patch[3] != "_":
|
||||
fontDc.DrawText(patch[3], 0, 0)
|
||||
eventDc.Blit(*absPoint, *self.cellSize, fontDc, 0, 0)
|
||||
# }}}
|
||||
# {{{ _finiBrushesAndPens(self)
|
||||
|
||||
def _finiBrushesAndPens(self):
|
||||
[brush.Destroy() for brush in self._brushes or []]
|
||||
[pen.Destroy() for pen in self._pens or []]
|
||||
self._brushes, self._lastBrushBg, self._lastBrushFg, self._lastPen, self._pens = None, None, None, None, None
|
||||
# }}}
|
||||
# {{{ _getBrushPatchColours(self, patch)
|
||||
|
||||
def _getBrushPatchColours(self, patch):
|
||||
if (patch[0] != -1) and (patch[1] != -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:
|
||||
brushBg, brushFg, pen = self._brushAlpha, self._brushAlpha, self._penAlpha
|
||||
return (brushBg, brushFg, pen)
|
||||
# }}}
|
||||
# {{{ _getCharPatchColours(self, patch)
|
||||
|
||||
def _getCharPatchColours(self, patch):
|
||||
if (patch[0] != -1) and (patch[1] != -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:
|
||||
brushBg, brushFg, pen = self._brushAlpha, self._brushAlpha, self._penAlpha
|
||||
return (brushBg, brushFg, pen)
|
||||
# }}}
|
||||
# {{{ _initBrushesAndPens(self)
|
||||
|
||||
def _initBrushesAndPens(self):
|
||||
self._brushes, self._pens = [None for x in range(len(Colours))], [None for x 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._penAlpha = wx.Pen(wx.Colour(Colours[14][:4]), 1)
|
||||
self._lastBrushBg, self._lastBrushFg, self._lastPen = None, None, None
|
||||
# }}}
|
||||
# {{{ _reshapeArabic(self, canvas, eventDc, patch, point)
|
||||
|
||||
def _reshapeArabic(self, canvas, eventDc, patch, point):
|
||||
lastCell = point[0]
|
||||
while True:
|
||||
@ -173,8 +162,7 @@ class GuiCanvasWxBackend():
|
||||
else:
|
||||
runCell[3] = self.arabicShapes[patch[5]][0]
|
||||
self._drawCharPatch(eventDc, runCell, [point[0], point[1]])
|
||||
# }}}
|
||||
# {{{ _setBrushDc(self, brushBg, brushFg, dc, pen)
|
||||
|
||||
def _setBrushDc(self, brushBg, brushFg, dc, pen):
|
||||
if self._lastBrushBg != brushBg:
|
||||
dc.SetBackground(brushBg); self._lastBrushBg = brushBg;
|
||||
@ -182,17 +170,14 @@ class GuiCanvasWxBackend():
|
||||
dc.SetBrush(brushFg); self._lastBrushFg = brushFg;
|
||||
if self._lastPen != pen:
|
||||
dc.SetPen(pen); self._lastPen = pen;
|
||||
# }}}
|
||||
# {{{ _xlatePoint(self, point)
|
||||
|
||||
def _xlatePoint(self, point):
|
||||
return [a * b for a, b in zip(point, self.cellSize)]
|
||||
# }}}
|
||||
|
||||
# {{{ drawCursorMaskWithJournal(self, canvas, canvasJournal, eventDc)
|
||||
|
||||
def drawCursorMaskWithJournal(self, canvas, canvasJournal, eventDc):
|
||||
[self.drawPatch(canvas, eventDc, patch) for patch in canvasJournal.popCursor()]
|
||||
# }}}
|
||||
# {{{ drawPatch(self, canvas, eventDc, patch)
|
||||
|
||||
def drawPatch(self, canvas, eventDc, patch):
|
||||
point = patch[:2]
|
||||
if [(c >= 0) and (c < s) for c, s in zip(point, self.canvasSize)] == [True, True]:
|
||||
@ -210,8 +195,7 @@ class GuiCanvasWxBackend():
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
# }}}
|
||||
# {{{ getDeviceContext(self, clientSize, parentWindow, viewRect=None)
|
||||
|
||||
def getDeviceContext(self, clientSize, parentWindow, viewRect=None):
|
||||
if viewRect == None:
|
||||
viewRect = parentWindow.GetViewStart()
|
||||
@ -221,16 +205,14 @@ class GuiCanvasWxBackend():
|
||||
eventDc = GuiBufferedDC(self, self.canvasBitmap, clientSize, wx.ClientDC(parentWindow), viewRect)
|
||||
self._lastBrushBg, self._lastBrushFg, self._lastPen = None, None, None
|
||||
return eventDc
|
||||
# }}}
|
||||
# {{{ onPaint(self, clientSize, panelWindow, viewRect)
|
||||
|
||||
def onPaint(self, clientSize, panelWindow, viewRect):
|
||||
if self.canvasBitmap != None:
|
||||
if viewRect == (0, 0):
|
||||
eventDc = wx.BufferedPaintDC(panelWindow, self.canvasBitmap)
|
||||
else:
|
||||
eventDc = GuiBufferedDC(self, self.canvasBitmap, clientSize, wx.PaintDC(panelWindow), viewRect)
|
||||
# }}}
|
||||
# {{{ resize(self, canvasSize, cellSize):
|
||||
|
||||
def resize(self, canvasSize, cellSize):
|
||||
winSize = [a * b for a, b in zip(canvasSize, cellSize)]
|
||||
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)
|
||||
else:
|
||||
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):
|
||||
eventPoint = event.GetLogicalPosition(eventDc)
|
||||
rectX, rectY = eventPoint.x - (eventPoint.x % self.cellSize[0]), eventPoint.y - (eventPoint.y % self.cellSize[1])
|
||||
mapX, mapY = int(rectX / self.cellSize[0] if rectX else 0), int(rectY / self.cellSize[1] if rectY else 0)
|
||||
return [m + n for m, n in zip((mapX, mapY), viewRect)]
|
||||
# }}}
|
||||
|
||||
# {{{ __del__(self): destructor method
|
||||
|
||||
def __del__(self):
|
||||
if self.canvasBitmap != None:
|
||||
self.canvasBitmap.Destroy(); self.canvasBitmap = None;
|
||||
self._finiBrushesAndPens()
|
||||
# }}}
|
||||
|
||||
|
||||
#
|
||||
# __init__(self, canvasSize, cellSize, fontName="Dejavu Sans Mono", fontPathName=os.path.join("assets", "fonts", "DejaVuSansMono.ttf")): initialisation method
|
||||
|
@ -4,11 +4,10 @@
|
||||
# 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
|
||||
# {{{ GuiCommandDecorator(targetObject)
|
||||
def GuiCommandDecorator(caption, label, icon, accel, initialState):
|
||||
def GuiCommandDecoratorOuter(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}
|
||||
return targetObject
|
||||
return GuiCommandDecoratorOuter
|
||||
# }}}
|
||||
# {{{ GuiCommandListDecorator(targetObject)
|
||||
|
||||
def GuiCommandListDecorator(idx, caption, label, icon, accel, initialState):
|
||||
def GuiCommandListDecoratorOuter(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})
|
||||
return targetObject
|
||||
return GuiCommandListDecoratorOuter
|
||||
# }}}
|
||||
# {{{ GuiSelectDecorator(targetObject)
|
||||
|
||||
def GuiSelectDecorator(idx, caption, label, icon, accel, initialState):
|
||||
def GuiSelectDecoratorOuter(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})
|
||||
return targetObject
|
||||
return GuiSelectDecoratorOuter
|
||||
# }}}
|
||||
# {{{ GuiSubMenuDecorator(targetObject)
|
||||
|
||||
def GuiSubMenuDecorator(caption, label, icon, accel, initialState):
|
||||
def GuiSubMenuDecoratorOuter(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}
|
||||
return targetObject
|
||||
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)
|
||||
@ -57,13 +65,11 @@ NID_MENU_SEP = 0xf000
|
||||
NID_TOOLBAR_HSEP = 0xf001
|
||||
|
||||
class GuiFrame(wx.Frame):
|
||||
# {{{ _initIcon(self, iconPathName)
|
||||
def _initIcon(self, iconPathName):
|
||||
icon = wx.Icon()
|
||||
icon.CopyFromBitmap(wx.Bitmap(iconPathName, wx.BITMAP_TYPE_ANY))
|
||||
self.SetIcon(icon)
|
||||
# }}}
|
||||
# {{{ _initMenu(self, menuItem, menuWindow)
|
||||
|
||||
def _initMenu(self, menuItem, menuWindow):
|
||||
if menuItem == NID_MENU_SEP:
|
||||
menuWindow.AppendSeparator()
|
||||
@ -87,10 +93,9 @@ class GuiFrame(wx.Frame):
|
||||
menuItemWindow.Check(menuItem.attrDict["initialState"])
|
||||
else:
|
||||
menuItemWindow.Enable(menuItem.attrDict["initialState"])
|
||||
# }}}
|
||||
|
||||
# {{{ loadAccels(self, menus, toolBars)
|
||||
def loadAccels(self, menus, toolBars):
|
||||
|
||||
def loadAccels(self, accelsIn, menus, toolBars):
|
||||
def loadAccels_(accels):
|
||||
nonlocal accelTableEntries
|
||||
accels_ = []
|
||||
@ -110,10 +115,9 @@ class GuiFrame(wx.Frame):
|
||||
self.itemsById[accel.attrDict["id"]] = accel
|
||||
self.Bind(wx.EVT_MENU, self.onMenu, id=accel.attrDict["id"])
|
||||
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))
|
||||
# }}}
|
||||
# {{{ loadBitmap(self, basePathName, descr, size=(16, 16))
|
||||
|
||||
def loadBitmap(self, basePathName, descr, size=(16, 16)):
|
||||
if descr == None:
|
||||
descr = ["", None, wx.ArtProvider.GetBitmap(wx.ART_HELP, wx.ART_TOOLBAR, size)]
|
||||
@ -126,8 +130,7 @@ class GuiFrame(wx.Frame):
|
||||
elif len(descr) == 3:
|
||||
descr = ("", None, descr[2])
|
||||
return descr
|
||||
# }}}
|
||||
# {{{ loadMenus(self, menus)
|
||||
|
||||
def loadMenus(self, menus):
|
||||
self.menuBar = wx.MenuBar()
|
||||
for menu in menus:
|
||||
@ -142,11 +145,11 @@ class GuiFrame(wx.Frame):
|
||||
self._initMenu(menuItem, menuWindow)
|
||||
self.menuBar.Append(menuWindow, menu[0])
|
||||
self.SetMenuBar(self.menuBar)
|
||||
# }}}
|
||||
# {{{ loadToolBars(self, toolBars)
|
||||
|
||||
def loadToolBars(self, 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))
|
||||
for toolBarItem in toolBar:
|
||||
if toolBarItem == NID_TOOLBAR_HSEP:
|
||||
@ -156,42 +159,40 @@ class GuiFrame(wx.Frame):
|
||||
toolBarItem.attrDict["id"] = wx.NewId()
|
||||
self.itemsById[toolBarItem.attrDict["id"]] = toolBarItem
|
||||
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:
|
||||
toolBarItemWindow = self.toolBars[-1].AddTool(toolBarItem.attrDict["id"], toolBarItem.attrDict["caption"], toolBarItem.attrDict["icon"][2], shortHelp=toolBarItem.attrDict["label"])
|
||||
self.toolBarItemsById[toolBarItem.attrDict["id"]] = toolBarItemWindow
|
||||
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"]] = (self.toolBars[-1], toolBarItemWindow,)
|
||||
self.Bind(wx.EVT_TOOL, self.onMenu, toolBarItemWindow)
|
||||
self.Bind(wx.EVT_TOOL_RCLICKED, self.onMenu, toolBarItemWindow)
|
||||
if toolBarItem.attrDict["initialState"] != None:
|
||||
if hasattr(toolBarItem, "isSelect"):
|
||||
toolBarItemWindow.Toggle(toolBarItem.attrDict["initialState"])
|
||||
if toolBarItem.attrDict["initialState"]:
|
||||
self.toolBars[-1].ToggleTool(toolBarItemWindow, True)
|
||||
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:
|
||||
self.sizerSkin.Add(toolBar, 0, wx.ALIGN_LEFT | wx.ALL, 3)
|
||||
toolBar.Realize(); toolBar.Fit();
|
||||
# }}}
|
||||
# {{{ 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;
|
||||
self.sizerSkin.Add(window, 0, flags, border); self.sizerSkin.Fit(self.panelSkin);
|
||||
# }}}
|
||||
# {{{ onChar(self, event)
|
||||
|
||||
def onChar(self, event):
|
||||
event.Skip()
|
||||
# }}}
|
||||
# {{{ onMenu(self, event)
|
||||
|
||||
def onMenu(self, event):
|
||||
eventId = event.GetId()
|
||||
if eventId in self.itemsById:
|
||||
self.itemsById[eventId](event)
|
||||
else:
|
||||
event.Skip()
|
||||
# }}}
|
||||
# {{{ onMouseWheel(self, event)
|
||||
|
||||
def onMouseWheel(self, event):
|
||||
event.Skip()
|
||||
# }}}
|
||||
|
||||
|
||||
#
|
||||
# __init__(self, iconPathName, size, parent=None, title=""): initialisation method
|
||||
|
@ -7,7 +7,6 @@
|
||||
import wx
|
||||
|
||||
class GuiWindow(wx.ScrolledWindow):
|
||||
# {{{ _updateScrollBars(self)
|
||||
def _updateScrollBars(self):
|
||||
if self.size != None:
|
||||
clientSize = self.GetClientSize()
|
||||
@ -16,48 +15,39 @@ class GuiWindow(wx.ScrolledWindow):
|
||||
elif self.scrollFlag \
|
||||
and ((self.size[0] <= clientSize[0]) or (self.size[1] <= clientSize[1])):
|
||||
self.scrollFlag = False; super().SetVirtualSize((0, 0));
|
||||
# }}}
|
||||
|
||||
# {{{ onClose(self, event)
|
||||
|
||||
def onClose(self, event):
|
||||
self.Destroy()
|
||||
# }}}
|
||||
# {{{ onEnterWindow(self, event)
|
||||
|
||||
def onEnterWindow(self, event):
|
||||
event.Skip()
|
||||
# }}}
|
||||
# {{{ onKeyboardInput(self, event)
|
||||
|
||||
def onKeyboardInput(self, event):
|
||||
return False
|
||||
# }}}
|
||||
# {{{ onLeaveWindow(self, event)
|
||||
|
||||
def onLeaveWindow(self, event):
|
||||
event.Skip()
|
||||
# }}}
|
||||
# {{{ onMouseInput(self, event)
|
||||
|
||||
def onMouseInput(self, event):
|
||||
return False
|
||||
# }}}
|
||||
# {{{ onPaint(self, event)
|
||||
|
||||
def onPaint(self, event):
|
||||
event.Skip()
|
||||
# }}}
|
||||
# {{{ onScroll(self, event)
|
||||
|
||||
def onScroll(self, event):
|
||||
event.Skip()
|
||||
# }}}
|
||||
# {{{ onSize(self, event)
|
||||
|
||||
def onSize(self, event):
|
||||
self._updateScrollBars(); event.Skip();
|
||||
# }}}
|
||||
# {{{ resize(self, newSize)
|
||||
|
||||
def resize(self, newSize):
|
||||
self.size = newSize; self._updateScrollBars();
|
||||
self.SetMinSize(self.size); self.SetSize(wx.DefaultCoord, wx.DefaultCoord, *self.size);
|
||||
curWindow = self
|
||||
while curWindow != None:
|
||||
curWindow.Layout(); curWindow = curWindow.GetParent();
|
||||
# }}}
|
||||
|
||||
|
||||
#
|
||||
# __init__(self, parent, pos, scrollStep, style=0): initialisation method
|
||||
|
@ -10,12 +10,10 @@ from GuiWindow import GuiWindow
|
||||
import json, os, sys, wx
|
||||
|
||||
class RoarAssetsWindow(GuiMiniFrame):
|
||||
# {{{ _drawPatch(self, canvas, eventDc, isCursor, patch)
|
||||
def _drawPatch(self, canvas, eventDc, isCursor, patch):
|
||||
if not isCursor:
|
||||
self.backend.drawPatch(canvas, eventDc, patch)
|
||||
# }}}
|
||||
# {{{ _import(self, f, pathName)
|
||||
|
||||
def _import(self, f, pathName):
|
||||
rc = False
|
||||
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
|
||||
self.SetCursor(wx.Cursor(wx.NullCursor))
|
||||
return rc, error, canvas, newMap, newPathName, newSize
|
||||
# }}}
|
||||
# {{{ _importFiles(self, f, wildcard)
|
||||
|
||||
def _importFiles(self, f, wildcard):
|
||||
resultList = []
|
||||
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)]
|
||||
self.lastDir = os.path.dirname(pathName)
|
||||
return resultList
|
||||
# }}}
|
||||
# {{{ _load_list(self, pathName)
|
||||
|
||||
def _load_list(self, pathName):
|
||||
try:
|
||||
with open(pathName, "r") as fileObject:
|
||||
@ -84,8 +80,7 @@ class RoarAssetsWindow(GuiMiniFrame):
|
||||
self.SetCursor(wx.Cursor(wx.NullCursor))
|
||||
with wx.MessageDialog(self, "Error: {}".format(str(e)), "", wx.OK | wx.OK_DEFAULT) as dialog:
|
||||
dialogChoice = dialog.ShowModal()
|
||||
# }}}
|
||||
# {{{ _updateScrollBars(self)
|
||||
|
||||
def _updateScrollBars(self):
|
||||
clientSize = self.panelCanvas.GetClientSize()
|
||||
if self.currentIndex != None:
|
||||
@ -99,9 +94,8 @@ class RoarAssetsWindow(GuiMiniFrame):
|
||||
elif self.scrollFlag \
|
||||
and ((panelSize[0] <= clientSize[0]) or (panelSize[1] <= clientSize[1])):
|
||||
self.scrollFlag = False; super(wx.ScrolledWindow, self.panelCanvas).SetVirtualSize((0, 0));
|
||||
# }}}
|
||||
|
||||
# {{{ drawCanvas(self, canvas)
|
||||
|
||||
def drawCanvas(self, canvas):
|
||||
panelSize = [a * b for a, b in zip(canvas.size, self.cellSize)]
|
||||
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]):
|
||||
self.backend.drawPatch(canvas, eventDc, [numCol, numRow, *canvas.map[numRow][numCol]])
|
||||
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
||||
# }}}
|
||||
# {{{ onPaint(self, event)
|
||||
|
||||
def onPaint(self, event):
|
||||
self.backend.onPaint(self.panelCanvas.GetClientSize(), self.panelCanvas, self.panelCanvas.GetViewStart())
|
||||
# }}}
|
||||
# {{{ onPanelLeftDown(self, event)
|
||||
|
||||
def onPanelLeftDown(self, event):
|
||||
self.panelCanvas.SetFocus()
|
||||
if (self.currentIndex != None):
|
||||
@ -130,16 +122,13 @@ class RoarAssetsWindow(GuiMiniFrame):
|
||||
dropSource.SetData(textDataObject)
|
||||
result = dropSource.DoDragDrop(True)
|
||||
event.Skip()
|
||||
# }}}
|
||||
# {{{ onPanelPaint(self, event)
|
||||
|
||||
def onPanelPaint(self, event):
|
||||
self.backend.onPaint(self.panelCanvas.GetClientSize(), self.panelCanvas, self.panelCanvas.GetViewStart())
|
||||
# }}}
|
||||
# {{{ onPanelSize(self, event)
|
||||
|
||||
def onPanelSize(self, event):
|
||||
self._updateScrollBars(); event.Skip();
|
||||
# }}}
|
||||
# {{{ resize(self, canvas, newSize)
|
||||
|
||||
def resize(self, canvas, newSize):
|
||||
oldSize = [0, 0] if canvas.map == None else canvas.size
|
||||
deltaSize = [b - a for a, b in zip(oldSize, newSize)]
|
||||
@ -161,8 +150,7 @@ class RoarAssetsWindow(GuiMiniFrame):
|
||||
for numNewCol in range(newSize[0]):
|
||||
self._drawPatch(canvas, eventDc, False, [numNewCol, numNewRow, 1, 1, 0, " "])
|
||||
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
||||
# }}}
|
||||
# {{{ update(self, canvas, newSize, newCanvas=None)
|
||||
|
||||
def update(self, canvas, newSize, newCanvas=None):
|
||||
self.resize(canvas, newSize);
|
||||
canvas.update(newSize, newCanvas);
|
||||
@ -172,21 +160,17 @@ class RoarAssetsWindow(GuiMiniFrame):
|
||||
for numCol in range(canvas.size[0]):
|
||||
self.backend.drawPatch(canvas, eventDc, [numCol, numRow, *canvas.map[numRow][numCol]])
|
||||
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
||||
# }}}
|
||||
|
||||
# {{{ onImportAnsi(self, event)
|
||||
|
||||
def onImportAnsi(self, event):
|
||||
event.Skip()
|
||||
# }}}
|
||||
# {{{ onImportFromClipboard(self, event)
|
||||
|
||||
def onImportFromClipboard(self, event):
|
||||
event.Skip()
|
||||
# }}}
|
||||
# {{{ onImportSauce(self, event)
|
||||
|
||||
def onImportSauce(self, event):
|
||||
event.Skip()
|
||||
# }}}
|
||||
# {{{ onChar(self, event)
|
||||
|
||||
def onChar(self, event):
|
||||
if (event.GetModifiers() == wx.MOD_NONE) \
|
||||
and (event.GetKeyCode() in (wx.WXK_DOWN, wx.WXK_UP)):
|
||||
@ -194,8 +178,7 @@ class RoarAssetsWindow(GuiMiniFrame):
|
||||
return wx.PostEvent(self.listView, event)
|
||||
else:
|
||||
event.Skip()
|
||||
# }}}
|
||||
# {{{ onListViewChar(self, event)
|
||||
|
||||
def onListViewChar(self, event):
|
||||
index, rc = self.listView.GetFirstSelected(), False
|
||||
if index != -1:
|
||||
@ -204,14 +187,12 @@ class RoarAssetsWindow(GuiMiniFrame):
|
||||
self.currentIndex, rc = index, True; self.onRemove(None);
|
||||
if not rc:
|
||||
event.Skip()
|
||||
# }}}
|
||||
# {{{ onListViewItemSelected(self, event)
|
||||
|
||||
def onListViewItemSelected(self, event):
|
||||
self.currentIndex = event.GetItem().GetId()
|
||||
item = [self.listView.GetItem(self.currentIndex, col).GetText() for col in (0, 1)]
|
||||
self.drawCanvas(self.canvasList[self.currentIndex][0])
|
||||
# }}}
|
||||
# {{{ onListViewRightDown(self, event)
|
||||
|
||||
def onListViewRightDown(self, event):
|
||||
eventPoint = event.GetPosition()
|
||||
if self.currentIndex == None:
|
||||
@ -223,8 +204,7 @@ class RoarAssetsWindow(GuiMiniFrame):
|
||||
else:
|
||||
self.contextMenuItems[4].Enable(True)
|
||||
self.PopupMenu(self.contextMenu, eventPoint)
|
||||
# }}}
|
||||
# {{{ onLoad(self, event)
|
||||
|
||||
def onLoad(self, event):
|
||||
def importmIRC(canvas, pathName):
|
||||
rc, error = canvas.importStore.importTextFile(pathName)
|
||||
@ -250,7 +230,7 @@ class RoarAssetsWindow(GuiMiniFrame):
|
||||
dialogChoice = dialog.ShowModal()
|
||||
if dialogChoice == wx.ID_CANCEL:
|
||||
break
|
||||
# }}}
|
||||
|
||||
# {{{ onLoadList(self, event)
|
||||
def onLoadList(self, event):
|
||||
rc = True
|
||||
@ -260,8 +240,7 @@ class RoarAssetsWindow(GuiMiniFrame):
|
||||
if dialog.ShowModal() != wx.ID_CANCEL:
|
||||
pathName = dialog.GetPath(); self.lastDir = os.path.dirname(pathName);
|
||||
self._load_list(pathName)
|
||||
# }}}
|
||||
# {{{ onRemove(self, event)
|
||||
|
||||
def onRemove(self, event):
|
||||
del self.canvasList[self.currentIndex]; self.listView.DeleteItem(self.currentIndex);
|
||||
itemCount = self.listView.GetItemCount()
|
||||
@ -280,8 +259,7 @@ class RoarAssetsWindow(GuiMiniFrame):
|
||||
self.currentIndex = None
|
||||
[self.listView.SetColumnWidth(col, wx.LIST_AUTOSIZE_USEHEADER) for col in (0, 1)]
|
||||
self.drawCanvas(Canvas((0, 0)))
|
||||
# }}}
|
||||
# {{{ onSaveList(self, event)
|
||||
|
||||
def onSaveList(self, event):
|
||||
rc = True
|
||||
if len(self.canvasList):
|
||||
@ -299,7 +277,7 @@ class RoarAssetsWindow(GuiMiniFrame):
|
||||
if not rc:
|
||||
with wx.MessageDialog(self, "Error: {}".format(error), "", wx.OK | wx.OK_DEFAULT) as dialog:
|
||||
dialogChoice = dialog.ShowModal()
|
||||
# }}}
|
||||
|
||||
|
||||
#
|
||||
# __init__(self, backend, cellSize, parent, pos=None, size=(400, 400), title="Assets"): initialisation method
|
||||
|
@ -14,19 +14,19 @@ from RoarCanvasCommandsTools import RoarCanvasCommandsTools
|
||||
import os, wx
|
||||
|
||||
class RoarCanvasCommands(RoarCanvasCommandsFile, RoarCanvasCommandsEdit, RoarCanvasCommandsTools, RoarCanvasCommandsOperators, RoarCanvasCommandsHelp):
|
||||
# {{{ _initColourBitmaps(self)
|
||||
def _initColourBitmaps(self):
|
||||
for numColour in range(len(RoarCanvasCommandsEdit.canvasColour.attrList)):
|
||||
def _initColourBitmaps_(cmd, cmdAlpha, div):
|
||||
for numColour in range(len(cmd.attrList)):
|
||||
if numColour < len(Colours):
|
||||
toolBitmapColour = Colours[numColour][0:4]
|
||||
toolBitmap = wx.Bitmap((16, 16))
|
||||
toolBitmapDc = wx.MemoryDC(); toolBitmapDc.SelectObject(toolBitmap);
|
||||
toolBitmapBrush = wx.Brush(wx.Colour(toolBitmapColour), wx.BRUSHSTYLE_SOLID)
|
||||
toolBitmapBrush = wx.Brush(wx.Colour([*[int(c / div) for c in toolBitmapColour[:3]], 255]), wx.BRUSHSTYLE_SOLID)
|
||||
toolBitmapDc.SetBrush(toolBitmapBrush)
|
||||
toolBitmapDc.SetBackground(toolBitmapBrush)
|
||||
toolBitmapDc.SetPen(wx.Pen(wx.Colour(toolBitmapColour), 1))
|
||||
toolBitmapDc.DrawRectangle(0, 0, 16, 16)
|
||||
RoarCanvasCommandsEdit.canvasColour.attrList[numColour]["icon"] = ["", None, toolBitmap]
|
||||
cmd.attrList[numColour]["icon"] = ["", None, toolBitmap]
|
||||
toolBitmapColours = ((0, 0, 0, 255), (255, 255, 255, 255))
|
||||
toolBitmap = wx.Bitmap((16, 16))
|
||||
toolBitmapDc = wx.MemoryDC(); toolBitmapDc.SelectObject(toolBitmap);
|
||||
@ -36,10 +36,11 @@ class RoarCanvasCommands(RoarCanvasCommandsFile, RoarCanvasCommandsEdit, RoarCan
|
||||
toolBitmapDc.SetPen(wx.Pen(wx.Colour(toolBitmapColours[1]), 1))
|
||||
toolBitmapDc.DrawRectangle(0, 0, 8, 8)
|
||||
toolBitmapDc.DrawRectangle(8, 8, 16, 16)
|
||||
RoarCanvasCommandsEdit.canvasColourAlpha.attrList[0]["icon"] = ["", None, toolBitmap]
|
||||
# }}}
|
||||
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):
|
||||
self.lastPanelState.update(kwargs); textItems = [];
|
||||
if "cellPos" in self.lastPanelState:
|
||||
@ -53,8 +54,20 @@ class RoarCanvasCommands(RoarCanvasCommandsFile, RoarCanvasCommandsEdit, RoarCan
|
||||
textItems.append("{} on {}".format(
|
||||
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"))
|
||||
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]
|
||||
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 self.lastPanelState["pathName"] != None:
|
||||
basePathName = os.path.basename(self.lastPanelState["pathName"])
|
||||
@ -75,35 +88,37 @@ class RoarCanvasCommands(RoarCanvasCommandsFile, RoarCanvasCommandsEdit, RoarCan
|
||||
and (self.lastPanelState["undoInhibit"]):
|
||||
for item in (self.canvasRedo, self.canvasUndo):
|
||||
self.parentFrame.menuItemsById[item.attrDict["id"]].Enable(False)
|
||||
toolBar = self.parentFrame.toolBarItemsById[item.attrDict["id"]].GetToolBar()
|
||||
toolBar.EnableTool(item.attrDict["id"], False)
|
||||
toolBar = self.parentFrame.toolBarItemsById[item.attrDict["id"]][0]
|
||||
toolBar.EnableTool(item.attrDict["id"], False); toolBar.Refresh();
|
||||
elif "undoLevel" in self.lastPanelState:
|
||||
if (self.lastPanelState["undoLevel"] >= 0) \
|
||||
and (self.lastPanelState["undoLevel"] < (len(self.parentCanvas.canvas.journal.patchesUndo) - 1)):
|
||||
self.parentFrame.menuItemsById[self.canvasUndo.attrDict["id"]].Enable(True)
|
||||
toolBar = self.parentFrame.toolBarItemsById[self.canvasUndo.attrDict["id"]].GetToolBar()
|
||||
toolBar.EnableTool(self.canvasUndo.attrDict["id"], True)
|
||||
toolBar = self.parentFrame.toolBarItemsById[self.canvasUndo.attrDict["id"]][0]
|
||||
toolBar.EnableTool(self.canvasUndo.attrDict["id"], True); toolBar.Refresh();
|
||||
else:
|
||||
self.parentFrame.menuItemsById[self.canvasUndo.attrDict["id"]].Enable(False)
|
||||
toolBar = self.parentFrame.toolBarItemsById[self.canvasUndo.attrDict["id"]].GetToolBar()
|
||||
toolBar.EnableTool(self.canvasUndo.attrDict["id"], False)
|
||||
toolBar = self.parentFrame.toolBarItemsById[self.canvasUndo.attrDict["id"]][0]
|
||||
toolBar.EnableTool(self.canvasUndo.attrDict["id"], False); toolBar.Refresh();
|
||||
if self.lastPanelState["undoLevel"] > 0:
|
||||
self.parentFrame.menuItemsById[self.canvasRedo.attrDict["id"]].Enable(True)
|
||||
toolBar = self.parentFrame.toolBarItemsById[self.canvasRedo.attrDict["id"]].GetToolBar()
|
||||
toolBar.EnableTool(self.canvasRedo.attrDict["id"], True)
|
||||
toolBar = self.parentFrame.toolBarItemsById[self.canvasRedo.attrDict["id"]][0]
|
||||
toolBar.EnableTool(self.canvasRedo.attrDict["id"], True); toolBar.Refresh();
|
||||
else:
|
||||
self.parentFrame.menuItemsById[self.canvasRedo.attrDict["id"]].Enable(False)
|
||||
toolBar = self.parentFrame.toolBarItemsById[self.canvasRedo.attrDict["id"]].GetToolBar()
|
||||
toolBar.EnableTool(self.canvasRedo.attrDict["id"], False)
|
||||
# }}}
|
||||
toolBar = self.parentFrame.toolBarItemsById[self.canvasRedo.attrDict["id"]][0]
|
||||
toolBar.EnableTool(self.canvasRedo.attrDict["id"], False); toolBar.Refresh();
|
||||
|
||||
|
||||
#
|
||||
# __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
|
||||
for classObject in self.__class__.__bases__:
|
||||
classObject.__init__(self)
|
||||
if len(self.accels):
|
||||
accels += self.accels
|
||||
if len(self.menus):
|
||||
menus += self.menus
|
||||
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.canvasUndo, self.canvasRedo, 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.canvasCanvasSize(self.canvasCanvasSize, 2, True), self.canvasCanvasSize(self.canvasCanvasSize, 2, False), NID_TOOLBAR_HSEP,
|
||||
self.canvasAssetsWindowHide, self.canvasAssetsWindowShow, 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),
|
||||
])
|
||||
# XXX
|
||||
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, 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, 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, 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
|
||||
|
@ -8,21 +8,26 @@ from GuiFrame import GuiCommandDecorator, GuiCommandListDecorator, GuiSelectDeco
|
||||
import wx
|
||||
|
||||
class RoarCanvasCommandsEdit():
|
||||
# {{{ canvasAssetsWindowHide(self, event)
|
||||
@GuiCommandDecorator("Hide assets window", "Hide assets window", None, None, False)
|
||||
@GuiCommandDecorator("Hide assets window", "Hide assets window", ["toolHideAssetsWindow.png"], None, False)
|
||||
def canvasAssetsWindowHide(self, event):
|
||||
self.parentFrame.assetsWindow.Show(False)
|
||||
self.parentFrame.menuItemsById[self.canvasAssetsWindowHide.attrDict["id"]].Enable(False)
|
||||
self.parentFrame.menuItemsById[self.canvasAssetsWindowShow.attrDict["id"]].Enable(True)
|
||||
# }}}
|
||||
# {{{ canvasAssetsWindowShow(self, event)
|
||||
@GuiCommandDecorator("Show assets window", "Show assets window", None, None, False)
|
||||
toolBar = self.parentFrame.toolBarItemsById[self.canvasAssetsWindowHide.attrDict["id"]][0]
|
||||
toolBar.EnableTool(self.canvasAssetsWindowHide.attrDict["id"], 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):
|
||||
self.parentFrame.assetsWindow.Show(True)
|
||||
self.parentFrame.menuItemsById[self.canvasAssetsWindowHide.attrDict["id"]].Enable(True)
|
||||
self.parentFrame.menuItemsById[self.canvasAssetsWindowShow.attrDict["id"]].Enable(False)
|
||||
# }}}
|
||||
# {{{ canvasBrush(self, f, idx)
|
||||
toolBar = self.parentFrame.toolBarItemsById[self.canvasAssetsWindowHide.attrDict["id"]][0]
|
||||
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)
|
||||
def canvasBrush(self, f, idx):
|
||||
def canvasBrush_(self, event):
|
||||
@ -30,14 +35,13 @@ class RoarCanvasCommandsEdit():
|
||||
setattr(canvasBrush_, "attrDict", f.attrList[idx])
|
||||
setattr(canvasBrush_, "isSelect", True)
|
||||
return canvasBrush_
|
||||
# }}}
|
||||
# {{{ canvasBrushSize(self, f, dimension, incrFlag)
|
||||
|
||||
@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(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(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_(event):
|
||||
if (dimension < 2) and not incrFlag:
|
||||
@ -49,16 +53,18 @@ class RoarCanvasCommandsEdit():
|
||||
self.update(brushSize=self.parentCanvas.brushSize)
|
||||
elif dimension == 2:
|
||||
[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)])
|
||||
return canvasBrushSize_
|
||||
# }}}
|
||||
# {{{ canvasCanvasSize(self, f, dimension, incrFlag)
|
||||
|
||||
@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(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(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_(event):
|
||||
if (dimension < 2) and not incrFlag:
|
||||
@ -77,8 +83,7 @@ class RoarCanvasCommandsEdit():
|
||||
[self.canvasCanvasSize(f, dimension_, incrFlag)(None) for dimension_ in [0, 1]]
|
||||
setattr(canvasCanvasSize_, "attrDict", f.attrList[dimension + (0 if not incrFlag else 3)])
|
||||
return canvasCanvasSize_
|
||||
# }}}
|
||||
# {{{ canvasColour(self, f, idx)
|
||||
|
||||
@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(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:
|
||||
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(canvasColour_, "attrDict", f.attrList[idx])
|
||||
setattr(canvasColour_, "isSelect", True)
|
||||
return canvasColour_
|
||||
# }}}
|
||||
# {{{ canvasColourAlpha(self, f, idx)
|
||||
|
||||
@GuiSelectDecorator(0, "Transparent colour", "Transparent colour", None, [wx.ACCEL_CTRL | wx.ACCEL_SHIFT, ord("6")], False)
|
||||
def canvasColourAlpha(self, f, idx):
|
||||
def canvasColourAlpha_(event):
|
||||
@ -115,55 +122,105 @@ class RoarCanvasCommandsEdit():
|
||||
elif event.GetEventType() == wx.wxEVT_TOOL_RCLICKED:
|
||||
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(canvasColourAlpha_, "attrDict", f.attrList[idx])
|
||||
setattr(canvasColourAlpha_, "isSelect", True)
|
||||
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)
|
||||
def canvasCopy(self, event):
|
||||
pass
|
||||
# }}}
|
||||
# {{{ canvasCut(self, event)
|
||||
|
||||
@GuiCommandDecorator("Cut", "Cu&t", ["", wx.ART_CUT], None, False)
|
||||
def canvasCut(self, event):
|
||||
pass
|
||||
# }}}
|
||||
# {{{ canvasDelete(self, event)
|
||||
|
||||
@GuiCommandDecorator("Delete", "De&lete", ["", wx.ART_DELETE], None, False)
|
||||
def canvasDelete(self, event):
|
||||
pass
|
||||
# }}}
|
||||
# {{{ canvasPaste(self, event)
|
||||
|
||||
@GuiCommandDecorator("Paste", "&Paste", ["", wx.ART_PASTE], None, False)
|
||||
def canvasPaste(self, event):
|
||||
pass
|
||||
# }}}
|
||||
# {{{ canvasRedo(self, event)
|
||||
|
||||
@GuiCommandDecorator("Redo", "&Redo", ["", wx.ART_REDO], [wx.ACCEL_CTRL, ord("Y")], False)
|
||||
def canvasRedo(self, event):
|
||||
self.parentCanvas.dispatchDeltaPatches(self.parentCanvas.canvas.journal.popRedo())
|
||||
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)
|
||||
def canvasUndo(self, event):
|
||||
self.parentCanvas.dispatchDeltaPatches(self.parentCanvas.canvas.journal.popUndo())
|
||||
self.update(size=self.parentCanvas.canvas.size, undoLevel=self.parentCanvas.canvas.journal.patchesUndoLevel)
|
||||
# }}}
|
||||
|
||||
|
||||
#
|
||||
# __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 = (
|
||||
("&Edit",
|
||||
self.canvasUndo, self.canvasRedo, NID_MENU_SEP,
|
||||
self.canvasCut, self.canvasCopy, self.canvasPaste,
|
||||
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,
|
||||
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,
|
||||
self.canvasBrush(self.canvasBrush, 0), NID_MENU_SEP,
|
||||
self.canvasAssetsWindowHide, self.canvasAssetsWindowShow,
|
||||
|
@ -21,7 +21,6 @@ from RtlPlatform import getLocalConfPathName
|
||||
import io, os, wx
|
||||
|
||||
class RoarCanvasCommandsFile():
|
||||
# {{{ _import(self, f, newDirty, pathName)
|
||||
def _import(self, f, newDirty, pathName):
|
||||
rc = False
|
||||
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
|
||||
@ -41,10 +40,9 @@ class RoarCanvasCommandsFile():
|
||||
dialogChoice = dialog.ShowModal()
|
||||
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
|
||||
return rc, newPathName
|
||||
# }}}
|
||||
# {{{ _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:
|
||||
dialog.SetDirectory(self.lastDir)
|
||||
if dialog.ShowModal() == wx.ID_CANCEL:
|
||||
@ -52,16 +50,14 @@ class RoarCanvasCommandsFile():
|
||||
elif self._promptSaveChanges():
|
||||
pathName = dialog.GetPath(); self.lastDir = os.path.dirname(pathName);
|
||||
return self._import(f, newDirty, pathName)
|
||||
# }}}
|
||||
# {{{ _loadRecent(self)
|
||||
|
||||
def _loadRecent(self):
|
||||
localConfFileName = getLocalConfPathName("Recent.lst")
|
||||
if os.path.exists(localConfFileName):
|
||||
with open(localConfFileName, "r", encoding="utf-8") as inFile:
|
||||
for lastFile in inFile.readlines():
|
||||
self._pushRecent(lastFile.rstrip("\r\n"), False)
|
||||
# }}}
|
||||
# {{{ _promptSaveChanges(self)
|
||||
|
||||
def _promptSaveChanges(self):
|
||||
if self.parentCanvas.dirty:
|
||||
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
|
||||
else:
|
||||
return True
|
||||
# }}}
|
||||
# {{{ _pushRecent(self, pathName, serialise=True)
|
||||
|
||||
def _pushRecent(self, pathName, serialise=True):
|
||||
menuItemId = wx.NewId()
|
||||
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:
|
||||
for lastFile in [l["pathName"] for l in self.lastFiles]:
|
||||
print(lastFile, file=outFile)
|
||||
# }}}
|
||||
|
||||
# {{{ canvasExit(self, event)
|
||||
|
||||
@GuiCommandDecorator("Exit", "E&xit", None, [wx.ACCEL_CTRL, ord("X")], None)
|
||||
def canvasExit(self, event):
|
||||
if self._promptSaveChanges():
|
||||
self.parentFrame.Close(True)
|
||||
# }}}
|
||||
|
||||
# {{{ canvasExportAsAnsi(self, event)
|
||||
|
||||
@GuiCommandDecorator("Export as ANSI...", "Export as &ANSI...", None, None, None)
|
||||
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:
|
||||
@ -119,8 +112,7 @@ class RoarCanvasCommandsFile():
|
||||
self.parentCanvas.canvas.exportStore.exportAnsiFile(self.parentCanvas.canvas.map, self.parentCanvas.canvas.size, outFile)
|
||||
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
|
||||
return True
|
||||
# }}}
|
||||
# {{{ canvasExportAsPng(self, event)
|
||||
|
||||
@GuiCommandDecorator("Export as PNG...", "Export as PN&G...", None, None, None)
|
||||
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:
|
||||
@ -134,8 +126,7 @@ class RoarCanvasCommandsFile():
|
||||
self.parentCanvas.canvas.exportStore.exportBitmapToPngFile(self.parentCanvas.backend.canvasBitmap, outPathName, wx.BITMAP_TYPE_PNG)
|
||||
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
|
||||
return True
|
||||
# }}}
|
||||
# {{{ canvasExportImgur(self, event)
|
||||
|
||||
@GuiCommandDecorator("Export to Imgur...", "Export to I&mgur...", None, None, haveImgurApiKey and haveUrllib)
|
||||
def canvasExportImgur(self, event):
|
||||
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)
|
||||
else:
|
||||
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)
|
||||
def canvasExportPastebin(self, event):
|
||||
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)
|
||||
else:
|
||||
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)
|
||||
def canvasExportToClipboard(self, event):
|
||||
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
|
||||
@ -173,17 +162,15 @@ class RoarCanvasCommandsFile():
|
||||
wx.TheClipboard.Close()
|
||||
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
|
||||
return True
|
||||
# }}}
|
||||
|
||||
# {{{ canvasImportAnsi(self, event)
|
||||
|
||||
@GuiCommandDecorator("Import ANSI...", "Import &ANSI...", None, None, None)
|
||||
def canvasImportAnsi(self, event):
|
||||
def canvasImportAnsi_(pathName):
|
||||
rc, error = self.parentCanvas.canvas.importStore.importAnsiFile(pathName)
|
||||
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 (*.*)|*.*")
|
||||
# }}}
|
||||
# {{{ canvasImportFromClipboard(self, event)
|
||||
|
||||
@GuiCommandDecorator("Import from clipboard", "Import from &clipboard", None, None, None)
|
||||
def canvasImportFromClipboard(self, event):
|
||||
def canvasImportFromClipboard_(pathName):
|
||||
@ -199,17 +186,15 @@ class RoarCanvasCommandsFile():
|
||||
return (rc, error, self.parentCanvas.canvas.importStore.outMap, None, self.parentCanvas.canvas.importStore.inSize)
|
||||
if self._promptSaveChanges():
|
||||
self._import(canvasImportFromClipboard_, True, None)
|
||||
# }}}
|
||||
# {{{ canvasImportSauce(self, event)
|
||||
|
||||
@GuiCommandDecorator("Import SAUCE...", "Import &SAUCE...", None, None, None)
|
||||
def canvasImportSauce(self, event):
|
||||
def canvasImportSauce_(pathName):
|
||||
rc, error = self.parentCanvas.canvas.importStore.importSauceFile(pathName)
|
||||
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 (*.*)|*.*")
|
||||
# }}}
|
||||
|
||||
# {{{ canvasNew(self, event, newCanvasSize=None)
|
||||
|
||||
@GuiCommandDecorator("New", "&New", ["", wx.ART_NEW], [wx.ACCEL_CTRL, ord("N")], None)
|
||||
def canvasNew(self, event, newCanvasSize=None):
|
||||
def canvasImportEmpty(pathName):
|
||||
@ -220,8 +205,7 @@ class RoarCanvasCommandsFile():
|
||||
return (True, "", newMap, None, newCanvasSize)
|
||||
if self._promptSaveChanges():
|
||||
self._import(canvasImportEmpty, False, None)
|
||||
# }}}
|
||||
# {{{ canvasOpen(self, event)
|
||||
|
||||
@GuiCommandDecorator("Open", "&Open", ["", wx.ART_FILE_OPEN], [wx.ACCEL_CTRL, ord("O")], None)
|
||||
def canvasOpen(self, event):
|
||||
def canvasImportmIRC(pathName):
|
||||
@ -230,16 +214,14 @@ class RoarCanvasCommandsFile():
|
||||
rc, newPathName = self._importFile(canvasImportmIRC, False, "mIRC art files (*.txt)|*.txt|All Files (*.*)|*.*")
|
||||
if rc:
|
||||
self._pushRecent(newPathName)
|
||||
# }}}
|
||||
# {{{ canvasOpenRecent(self, event, pathName=None)
|
||||
|
||||
@GuiSubMenuDecorator("Open Recent", "Open &Recent", None, None, False)
|
||||
def canvasOpenRecent(self, event, pathName=None):
|
||||
def canvasImportmIRC(pathName):
|
||||
rc, error = self.parentCanvas.canvas.importStore.importTextFile(pathName)
|
||||
return (rc, error, self.parentCanvas.canvas.importStore.outMap, pathName, self.parentCanvas.canvas.importStore.inSize)
|
||||
self._import(canvasImportmIRC, False, pathName)
|
||||
# }}}
|
||||
# {{{ canvasSave(self, event)
|
||||
|
||||
@GuiCommandDecorator("Save", "&Save", ["", wx.ART_FILE_SAVE], [wx.ACCEL_CTRL, ord("S")], None)
|
||||
def canvasSave(self, event, newDirty=False):
|
||||
if self.canvasPathName == None:
|
||||
@ -256,8 +238,7 @@ class RoarCanvasCommandsFile():
|
||||
return True
|
||||
except IOError as error:
|
||||
return False
|
||||
# }}}
|
||||
# {{{ canvasSaveAs(self, event)
|
||||
|
||||
@GuiCommandDecorator("Save As...", "Save &As...", ["", wx.ART_FILE_SAVE_AS], None, None)
|
||||
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:
|
||||
@ -269,12 +250,13 @@ class RoarCanvasCommandsFile():
|
||||
self.canvasPathName = dialog.GetPath(); self.lastDir = os.path.dirname(self.canvasPathName);
|
||||
if self.canvasSave(event, newDirty=True):
|
||||
self._pushRecent(self.canvasPathName)
|
||||
# }}}
|
||||
|
||||
|
||||
#
|
||||
# __init__(self)
|
||||
def __init__(self):
|
||||
self.imgurApiKey, self.lastFiles, self.lastDir = ImgurApiKey.imgurApiKey if haveImgurApiKey else None, [], None
|
||||
self.accels = ()
|
||||
self.menus = (
|
||||
("&File",
|
||||
self.canvasNew, self.canvasOpen, self.canvasOpenRecent, self.canvasSave, self.canvasSaveAs, NID_MENU_SEP,
|
||||
|
@ -8,15 +8,15 @@ from GuiFrame import GuiCommandDecorator
|
||||
from RoarWindowAbout import RoarWindowAbout
|
||||
|
||||
class RoarCanvasCommandsHelp():
|
||||
# {{{ canvasAbout(self, event)
|
||||
@GuiCommandDecorator("About", "&About", None, None, True)
|
||||
def canvasAbout(self, event):
|
||||
RoarWindowAbout(self.parentFrame)
|
||||
# }}}
|
||||
|
||||
|
||||
#
|
||||
# __init__(self)
|
||||
def __init__(self):
|
||||
self.accels = ()
|
||||
self.menus, self.toolBars = (("&Help", self.canvasAbout,),), ()
|
||||
|
||||
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=0
|
||||
|
@ -14,10 +14,9 @@ from ToolObject import ToolObject
|
||||
import copy, wx
|
||||
|
||||
class RoarCanvasCommandsOperators():
|
||||
# {{{ canvasOperator(self, f, idx)
|
||||
@GuiCommandListDecorator(0, "Flip", "&Flip", 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(4, "Tile", "&Tile", None, None, None)
|
||||
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())
|
||||
setattr(canvasOperator_, "attrDict", f.attrList[idx])
|
||||
return canvasOperator_
|
||||
# }}}
|
||||
|
||||
|
||||
#
|
||||
# __init__(self)
|
||||
def __init__(self):
|
||||
self.accels = ()
|
||||
self.menus = (
|
||||
("&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),
|
||||
|
@ -14,7 +14,6 @@ from ToolText import ToolText
|
||||
import wx
|
||||
|
||||
class RoarCanvasCommandsTools():
|
||||
# {{{ canvasTool(self, f, idx)
|
||||
@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(2, "Fill", "&Fill", ["toolFill.png"], [wx.ACCEL_CTRL, ord("F")], False)
|
||||
@ -33,23 +32,24 @@ class RoarCanvasCommandsTools():
|
||||
self.currentTool = self.currentTool()
|
||||
self.currentOperator, self.operatorState = None, None
|
||||
self.parentFrame.menuItemsById[self.canvasTool.attrList[idx]["id"]].Check(True)
|
||||
toolBar = self.parentFrame.toolBarItemsById[self.canvasTool.attrList[idx]["id"]].GetToolBar()
|
||||
toolBar.ToggleTool(self.canvasTool.attrList[idx]["id"], True)
|
||||
toolBar = self.parentFrame.toolBarItemsById[self.canvasTool.attrList[idx]["id"]][0]
|
||||
toolBar.ToggleTool(self.canvasTool.attrList[idx]["id"], True); toolBar.Refresh();
|
||||
if self.currentTool != None:
|
||||
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:
|
||||
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_, "isSelect", True)
|
||||
return canvasTool_
|
||||
# }}}
|
||||
|
||||
|
||||
#
|
||||
# __init__(self)
|
||||
def __init__(self):
|
||||
self.accels = ()
|
||||
self.menus = (
|
||||
("&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),
|
||||
|
@ -10,11 +10,9 @@ from ToolText import ToolText
|
||||
import copy, json, wx, sys
|
||||
|
||||
class RoarCanvasWindowDropTarget(wx.TextDropTarget):
|
||||
# {{{ done(self)
|
||||
def done(self):
|
||||
self.inProgress = False
|
||||
# }}}
|
||||
# {{{ OnDropText(self, x, y, data)
|
||||
|
||||
def OnDropText(self, x, y, data):
|
||||
rc = False
|
||||
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:
|
||||
dialogChoice = dialog.ShowModal()
|
||||
return rc
|
||||
# }}}
|
||||
# {{{ __init__(self, parent)
|
||||
|
||||
def __init__(self, parent):
|
||||
super().__init__(); self.inProgress, self.parent = False, parent;
|
||||
# }}}
|
||||
|
||||
|
||||
class RoarCanvasWindow(GuiWindow):
|
||||
# {{{ _drawPatch(self, eventDc, isCursor, patch)
|
||||
def _drawPatch(self, eventDc, isCursor, patch):
|
||||
if not self.canvas.dirtyCursor:
|
||||
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:
|
||||
patchDeltaCell = self.canvas.map[patch[1]][patch[0]]; patchDelta = [*patch[0:2], *patchDeltaCell];
|
||||
self.canvas.journal.pushCursor(patchDelta)
|
||||
# }}}
|
||||
|
||||
# {{{ applyOperator(self, currentTool, mapPoint, mouseLeftDown, mousePoint, operator, viewRect)
|
||||
|
||||
def applyOperator(self, currentTool, mapPoint, mouseLeftDown, mousePoint, operator, viewRect):
|
||||
self.canvas.dirtyCursor = False
|
||||
if (currentTool.__class__ == ToolObject) \
|
||||
@ -94,15 +89,14 @@ class RoarCanvasWindow(GuiWindow):
|
||||
self.canvas.journal.end()
|
||||
self.commands.update(dirty=self.dirty, undoLevel=self.canvas.journal.patchesUndoLevel)
|
||||
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):
|
||||
|
||||
def applyTool(self, eventDc, eventMouse, keyChar, keyCode, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown, tool, viewRect, force=False):
|
||||
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
|
||||
self.canvas.journal.begin()
|
||||
if eventMouse:
|
||||
if force:
|
||||
self.lastCellState = None
|
||||
if ((mapPoint[0] < self.canvas.size[0]) \
|
||||
and (mapPoint[1] < self.canvas.size[1])) \
|
||||
and ((self.lastCellState == None) \
|
||||
@ -140,8 +134,7 @@ class RoarCanvasWindow(GuiWindow):
|
||||
self.commands.update(undoInhibit=False)
|
||||
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
||||
return rc
|
||||
# }}}
|
||||
# {{{ dispatchDeltaPatches(self, deltaPatches)
|
||||
|
||||
def dispatchDeltaPatches(self, deltaPatches):
|
||||
eventDc = self.backend.getDeviceContext(self.GetClientSize(), self)
|
||||
eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0);
|
||||
@ -158,19 +151,17 @@ class RoarCanvasWindow(GuiWindow):
|
||||
else:
|
||||
self.canvas._commitPatch(patch); self.backend.drawPatch(self.canvas, eventDc, patch)
|
||||
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
||||
# }}}
|
||||
# {{{ dispatchPatch(self, eventDc, isCursor, patch)
|
||||
|
||||
def dispatchPatch(self, eventDc, isCursor, patch):
|
||||
if self.canvas.dispatchPatch(isCursor, patch, False if isCursor else True):
|
||||
self._drawPatch(eventDc, isCursor, patch)
|
||||
# }}}
|
||||
# {{{ dispatchPatchSingle(self, eventDc, isCursor, patch)
|
||||
|
||||
def dispatchPatchSingle(self, eventDc, isCursor, patch):
|
||||
if self.canvas.dispatchPatchSingle(isCursor, patch, False if isCursor else True):
|
||||
self._drawPatch(eventDc, isCursor, patch)
|
||||
# }}}
|
||||
# {{{ 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
|
||||
deltaSize = [b - a for a, b in zip(oldSize, newSize)]
|
||||
if self.canvas.resize(newSize, commitUndo):
|
||||
@ -187,9 +178,9 @@ class RoarCanvasWindow(GuiWindow):
|
||||
for numNewCol in range(newSize[0]):
|
||||
self._drawPatch(eventDc, False, [numNewCol, numNewRow, 1, 1, 0, " "])
|
||||
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
||||
self.Scroll(*viewRect)
|
||||
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):
|
||||
self.resize(newSize, commitUndo)
|
||||
self.canvas.update(newSize, newCanvas)
|
||||
@ -199,9 +190,8 @@ class RoarCanvasWindow(GuiWindow):
|
||||
for numCol in range(newSize[0]):
|
||||
self.backend.drawPatch(self.canvas, eventDc, [numCol, numRow, *self.canvas.map[numRow][numCol]])
|
||||
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
||||
# }}}
|
||||
|
||||
# {{{ onKeyboardInput(self, event)
|
||||
|
||||
def onKeyboardInput(self, event):
|
||||
keyCode, keyModifiers = event.GetKeyCode(), event.GetModifiers()
|
||||
viewRect = self.GetViewStart(); eventDc = self.backend.getDeviceContext(self.GetClientSize(), self, viewRect);
|
||||
@ -245,12 +235,10 @@ class RoarCanvasWindow(GuiWindow):
|
||||
else:
|
||||
if not self.applyTool(eventDc, False, chr(event.GetUnicodeKey()), keyCode, keyModifiers, None, None, None, None, self.commands.currentTool, viewRect):
|
||||
event.Skip()
|
||||
# }}}
|
||||
# {{{ onEnterWindow(self, event)
|
||||
|
||||
def onEnterWindow(self, event):
|
||||
self.lastCellState = None
|
||||
# }}}
|
||||
# {{{ onLeaveWindow(self, event)
|
||||
|
||||
def onLeaveWindow(self, event):
|
||||
if False:
|
||||
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)
|
||||
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
||||
self.lastCellState = None
|
||||
# }}}
|
||||
# {{{ onMouseInput(self, event)
|
||||
|
||||
def onMouseInput(self, event):
|
||||
viewRect = self.GetViewStart(); eventDc = self.backend.getDeviceContext(self.GetClientSize(), self, viewRect);
|
||||
mouseDragging, mouseLeftDown, mouseRightDown = event.Dragging(), event.LeftIsDown(), event.RightIsDown()
|
||||
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:
|
||||
self.applyOperator(self.commands.currentTool, mapPoint, mouseLeftDown, event.GetLogicalPosition(eventDc), self.commands.currentOperator, viewRect)
|
||||
elif mouseRightDown \
|
||||
@ -272,8 +261,7 @@ class RoarCanvasWindow(GuiWindow):
|
||||
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):
|
||||
event.Skip()
|
||||
# }}}
|
||||
# {{{ onMouseWheel(self, event)
|
||||
|
||||
def onMouseWheel(self, event):
|
||||
if event.GetModifiers() == wx.MOD_CONTROL:
|
||||
cd = +1 if event.GetWheelRotation() >= event.GetWheelDelta() else -1
|
||||
@ -290,15 +278,14 @@ class RoarCanvasWindow(GuiWindow):
|
||||
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
||||
else:
|
||||
event.Skip()
|
||||
# }}}
|
||||
# {{{ onPaint(self, event)
|
||||
|
||||
def onPaint(self, event):
|
||||
eventDc = self.backend.getDeviceContext(self.GetClientSize(), self)
|
||||
eventDcOrigin = eventDc.GetDeviceOrigin(); eventDc.SetDeviceOrigin(0, 0);
|
||||
self.backend.drawCursorMaskWithJournal(self.canvas, self.canvas.journal, eventDc)
|
||||
eventDc.SetDeviceOrigin(*eventDcOrigin)
|
||||
self.backend.onPaint(self.GetClientSize(), self, self.GetViewStart())
|
||||
# }}}
|
||||
|
||||
|
||||
#
|
||||
# __init__(self, backend, canvas, cellSize, commands, parent, parentFrame, pos, scrollStep, size): initialisation method
|
||||
|
@ -15,27 +15,23 @@ from glob import glob
|
||||
import os, random, sys, wx
|
||||
|
||||
class RoarClient(GuiFrame):
|
||||
# {{{ _getIconPathName(self)
|
||||
def _getIconPathName(self):
|
||||
iconPathNames = glob(os.path.join("assets", "images", "logo*.bmp"))
|
||||
return iconPathNames[random.randint(0, len(iconPathNames) - 1)]
|
||||
# }}}
|
||||
# {{{ _initToolBitmaps(self, toolBars)
|
||||
|
||||
def _initToolBitmaps(self, toolBars):
|
||||
basePathName = os.path.join(os.path.dirname(sys.argv[0]), "assets", "images")
|
||||
for toolBar in toolBars:
|
||||
for toolBarItem in [i for i in toolBar if i != NID_TOOLBAR_HSEP]:
|
||||
toolBarItem.attrDict["icon"] = self.loadBitmap(basePathName, toolBarItem.attrDict["icon"])
|
||||
# }}}
|
||||
|
||||
# {{{ onChar(self, event)
|
||||
|
||||
def onChar(self, event):
|
||||
self.canvasPanel.onKeyboardInput(event)
|
||||
# }}}
|
||||
# {{{ onMouseWheel(self, event)
|
||||
|
||||
def onMouseWheel(self, event):
|
||||
self.canvasPanel.GetEventHandler().ProcessEvent(event)
|
||||
# }}}
|
||||
|
||||
|
||||
#
|
||||
# __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)
|
||||
self.canvas = Canvas(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._initToolBitmaps(self.canvasPanel.commands.toolBars)
|
||||
self.loadToolBars(self.canvasPanel.commands.toolBars)
|
||||
|
@ -8,10 +8,9 @@ from glob import glob
|
||||
import os, random, wx, wx.adv
|
||||
|
||||
class RoarWindowAbout(wx.Dialog):
|
||||
# {{{ onButtonRoar(self, event)
|
||||
def onButtonRoar(self, event):
|
||||
self.Destroy()
|
||||
# }}}
|
||||
|
||||
|
||||
#
|
||||
# __init__(self, parent, minSize=(320, 300), title="About roar")
|
||||
|
@ -11,13 +11,11 @@ import select, socket, time
|
||||
class IrcClient:
|
||||
"""Non-blocking abstraction over the IRC protocol"""
|
||||
|
||||
# {{{ close(self): Close connection to server
|
||||
def close(self):
|
||||
if self.clientSocket != None:
|
||||
self.clientSocket.close()
|
||||
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):
|
||||
gaiInfo = socket.getaddrinfo(self.serverHname, self.serverPort,
|
||||
preferFamily, socket.SOCK_STREAM, socket.IPPROTO_TCP)
|
||||
@ -41,8 +39,7 @@ class IrcClient:
|
||||
self.queue("NICK", self.clientNick)
|
||||
self.queue("USER", self.clientIdent, "0", "0", self.clientGecos)
|
||||
return True
|
||||
# }}}
|
||||
# {{{ queue(self, *args): Parse and queue single line to server from list
|
||||
|
||||
def queue(self, *args):
|
||||
msg = ""; argNumMax = len(args);
|
||||
for argNum in range(argNumMax):
|
||||
@ -51,8 +48,7 @@ class IrcClient:
|
||||
else:
|
||||
msg += args[argNum] + " "
|
||||
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):
|
||||
if self.clientNextTimeout:
|
||||
timeNow = time.time()
|
||||
@ -85,8 +81,7 @@ class IrcClient:
|
||||
else:
|
||||
msg = [""] + msg[0:]
|
||||
return msg
|
||||
# }}}
|
||||
# {{{ unqueue(self, timeout=15): Send all queued lines to server, honouring timers
|
||||
|
||||
def unqueue(self, timeout=15):
|
||||
while self.clientQueue:
|
||||
msg = self.clientQueue[0]; msgLen = len(msg); msgBytesSent = 0;
|
||||
@ -111,7 +106,7 @@ class IrcClient:
|
||||
msg = msg[msgBytesSent:]; msgLen -= msgBytesSent;
|
||||
del self.clientQueue[0]
|
||||
return True
|
||||
# }}}
|
||||
|
||||
|
||||
#
|
||||
# __init__(self, serverHname, serverPort, clientNick, clientIdent, clientGecos): initialisation method
|
||||
|
@ -7,10 +7,9 @@
|
||||
|
||||
import os, platform
|
||||
|
||||
# {{{ getLocalConfPathName(*args)
|
||||
def getLocalConfPathName(*args):
|
||||
vname = "LOCALAPPDATA" if platform.system() == "Windows" else "HOME"
|
||||
return os.path.join(os.getenv(vname), "roar", *args)
|
||||
# }}}
|
||||
|
||||
|
||||
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
||||
|
@ -5,13 +5,11 @@
|
||||
#
|
||||
|
||||
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):
|
||||
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):
|
||||
return False, False
|
||||
# }}}
|
||||
|
||||
|
||||
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120
|
||||
|
@ -12,22 +12,37 @@ class ToolCircle(Tool):
|
||||
#
|
||||
# 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
|
||||
if mouseLeftDown:
|
||||
brushColours[1] = brushColours[0]
|
||||
elif mouseRightDown:
|
||||
brushColours[0] = brushColours[1]
|
||||
else:
|
||||
brushColours[1] = brushColours[0]
|
||||
_brushSize = brushSize[0] * 2
|
||||
originPoint, radius = (_brushSize / 2, _brushSize / 2), _brushSize
|
||||
brushColours, brushSize, dirty = list(brushColours), [brushSize[0] * 2, brushSize[1]], False
|
||||
originPoint, radius = (brushSize[0] / 2, brushSize[0] / 2), brushSize[0]
|
||||
if mouseRightDown:
|
||||
brushColours = [brushColours[1], brushColours[0]]
|
||||
cells = []
|
||||
for brushY in range(-radius, radius + 1):
|
||||
cells += [[]]
|
||||
for brushX in range(-radius, radius + 1):
|
||||
if ((brushX ** 2) + (brushY ** 2) < (((radius ** 2) + radius) * 0.8)):
|
||||
patch = [ \
|
||||
mapPoint[0] + int(originPoint[0] + brushX), \
|
||||
mapPoint[1] + int(originPoint[1] + brushY), \
|
||||
*brushColours, 0, " "]
|
||||
cells[-1] += [[mapPoint[i] + int(originPoint[i] + o) for i, o in zip((0, 1,), (brushX, brushY,))]]
|
||||
if cells[-1] == []:
|
||||
del cells[-1]
|
||||
for numRow in range(len(cells)):
|
||||
for numCol in range(len(cells[numRow])):
|
||||
if ((numRow == 0) or (numRow == (len(cells) - 1))) \
|
||||
or ((numCol == 0) or (numCol == (len(cells[numRow]) - 1))):
|
||||
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:
|
||||
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
|
||||
|
@ -5,6 +5,7 @@
|
||||
#
|
||||
|
||||
from Tool import Tool
|
||||
import wx
|
||||
|
||||
class ToolFill(Tool):
|
||||
name = "Fill"
|
||||
@ -14,15 +15,19 @@ class ToolFill(Tool):
|
||||
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]
|
||||
if mouseLeftDown or mouseRightDown:
|
||||
if mouseLeftDown:
|
||||
fillColour = brushColours[0]
|
||||
else:
|
||||
fillColour = brushColours[1]
|
||||
while len(pointStack) > 0:
|
||||
point = pointStack.pop()
|
||||
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])):
|
||||
if not point in pointsDone:
|
||||
if not dirty:
|
||||
dirty = True
|
||||
dispatchFn(eventDc, False, [*point, brushColours[0], brushColours[0], 0, " "])
|
||||
dispatchFn(eventDc, False, [*point, fillColour, fillColour, 0, " "])
|
||||
if point[0] > 0:
|
||||
pointStack.append([point[0] - 1, point[1]])
|
||||
if point[0] < (canvas.size[0] - 1):
|
||||
|
@ -11,7 +11,6 @@ class ToolLine(Tool):
|
||||
TS_NONE = 0
|
||||
TS_ORIGIN = 1
|
||||
|
||||
# {{{ _getLine(self, brushColours, brushSize, dispatchFn, eventDc, isCursor, originPoint, targetPoint)
|
||||
def _getLine(self, brushColours, brushSize, dispatchFn, eventDc, isCursor, originPoint, targetPoint):
|
||||
dirty = False
|
||||
originPoint, targetPoint = originPoint.copy(), targetPoint.copy()
|
||||
@ -40,15 +39,13 @@ class ToolLine(Tool):
|
||||
lineD -= pointDelta[0]; lineY += 1;
|
||||
lineD += pointDelta[1]
|
||||
return dirty
|
||||
# }}}
|
||||
# {{{ _pointDelta(self, a, b)
|
||||
|
||||
def _pointDelta(self, a, b):
|
||||
return [a2 - a1 for a1, a2 in zip(a, b)]
|
||||
# }}}
|
||||
# {{{ _pointSwap(self, a, b)
|
||||
|
||||
def _pointSwap(self, a, b):
|
||||
return [b, a]
|
||||
# }}}
|
||||
|
||||
|
||||
#
|
||||
# onMouseEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown, mouseRightDown)
|
||||
|
@ -14,7 +14,6 @@ class ToolObject(Tool):
|
||||
TS_SELECT = 2
|
||||
TS_TARGET = 3
|
||||
|
||||
# {{{ _dispatchSelectEvent(self, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseLeftDown, selectRect)
|
||||
def _dispatchSelectEvent(self, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseLeftDown, selectRect):
|
||||
if mouseLeftDown:
|
||||
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.targetRect = newTargetRect
|
||||
return dirty
|
||||
# }}}
|
||||
# {{{ _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)]
|
||||
if rectFrame[0][0] > rectFrame[1][0]:
|
||||
@ -43,8 +41,7 @@ class ToolObject(Tool):
|
||||
curColours = [1, 1] if curColours == [0, 0] else [0, 0]
|
||||
dispatchFn(eventDc, True, [rectFrame[0][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):
|
||||
self.substract = False
|
||||
if self.external:
|
||||
@ -55,11 +52,10 @@ class ToolObject(Tool):
|
||||
else:
|
||||
dispatchFn(eventDc, True, [*mapPoint, *brushColours, 0, " "])
|
||||
return False
|
||||
# }}}
|
||||
# {{{ _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)
|
||||
if mouseLeftDown:
|
||||
if not mouseLeftDown:
|
||||
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]
|
||||
if self.targetRect[0][1] > self.targetRect[1][1]:
|
||||
@ -74,8 +70,7 @@ class ToolObject(Tool):
|
||||
else:
|
||||
self._drawSelectRect(self.targetRect, dispatchFn, eventDc)
|
||||
return False
|
||||
# }}}
|
||||
# {{{ _mouseEventTsSelect(self, brushColours, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown)
|
||||
|
||||
def _mouseEventTsSelect(self, brushColours, canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseDragging, mouseLeftDown):
|
||||
dirty = False
|
||||
if mouseLeftDown:
|
||||
@ -91,8 +86,7 @@ class ToolObject(Tool):
|
||||
else:
|
||||
dirty = self._dispatchSelectEvent(canvas, dispatchFn, eventDc, keyModifiers, mapPoint, mouseLeftDown, self.targetRect)
|
||||
return dirty
|
||||
# }}}
|
||||
# {{{ _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):
|
||||
self.substract = True
|
||||
@ -102,13 +96,11 @@ class ToolObject(Tool):
|
||||
else:
|
||||
self.toolState = self.TS_SELECT
|
||||
return dirty
|
||||
# }}}
|
||||
|
||||
# {{{ getRegion(self, canvas)
|
||||
|
||||
def getRegion(self, canvas):
|
||||
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):
|
||||
dirty = False
|
||||
if self.toolState == self.TS_NONE:
|
||||
@ -122,8 +114,7 @@ class ToolObject(Tool):
|
||||
else:
|
||||
return False, 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):
|
||||
dirty = False
|
||||
if self.external:
|
||||
@ -149,10 +140,13 @@ class ToolObject(Tool):
|
||||
cellOld = self.objectMap[numRow][numCol]
|
||||
rectX, rectY = selectRect[0][0] + numCol, selectRect[0][1] + numRow
|
||||
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
|
||||
# }}}
|
||||
# {{{ 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
|
||||
if mapPoint != None:
|
||||
@ -166,7 +160,7 @@ class ToolObject(Tool):
|
||||
if self.srcRect == None:
|
||||
self.srcRect = self.targetRect
|
||||
self.objectMap, self.objectSize = objectMap, objectSize
|
||||
# }}}
|
||||
|
||||
|
||||
# __init__(self, *args): initialisation method
|
||||
def __init__(self, *args):
|
||||
|
@ -12,19 +12,26 @@ class ToolRect(Tool):
|
||||
#
|
||||
# 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
|
||||
if mouseLeftDown:
|
||||
brushColours[1] = brushColours[0]
|
||||
elif mouseRightDown:
|
||||
brushColours[0] = brushColours[1]
|
||||
else:
|
||||
brushColours[1] = brushColours[0]
|
||||
brushSize = brushSize.copy()
|
||||
brushColours, brushSize, dirty = list(brushColours), list(brushSize), False
|
||||
if mouseRightDown:
|
||||
brushColours = [brushColours[1], brushColours[0]]
|
||||
if brushSize[0] > 1:
|
||||
brushSize[0] *= 2
|
||||
for brushRow in range(brushSize[1]):
|
||||
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 not dirty:
|
||||
dirty = True
|
||||
|
@ -13,7 +13,6 @@ class ToolText(Tool):
|
||||
arabicRegEx = r'^[\u0621-\u063A\u0640-\u064A]+$'
|
||||
rtlRegEx = r'^[\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC]+$'
|
||||
|
||||
# {{{ _checkRtl(self, canvas, brushPos, keyChar)
|
||||
def _checkRtl(self, canvas, brushPos, keyChar):
|
||||
rtlFlag = False
|
||||
if (keyChar != None) and re.match(self.rtlRegEx, keyChar):
|
||||
@ -41,13 +40,11 @@ class ToolText(Tool):
|
||||
else:
|
||||
break
|
||||
return rtlFlag
|
||||
# }}}
|
||||
# {{{ _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) \
|
||||
and (not keyChar in set("\t\n\v\f\r")) \
|
||||
and ((ord(keyChar) >= 32) if ord(keyChar) < 127 else True) \
|
||||
and (keyModifiers in (wx.MOD_NONE, wx.MOD_SHIFT)):
|
||||
and ((ord(keyChar) >= 32) if ord(keyChar) < 127 else True):
|
||||
dispatchFn(eventDc, False, [*brushPos, *brushColours, 0, keyChar]);
|
||||
if not self._checkRtl(canvas, brushPos, keyChar):
|
||||
if brushPos[0] < (canvas.size[0] - 1):
|
||||
@ -67,7 +64,7 @@ class ToolText(Tool):
|
||||
else:
|
||||
rc, dirty = False, False
|
||||
return rc, dirty
|
||||
# }}}
|
||||
|
||||
|
||||
#
|
||||
# onKeyboardEvent(self, atPoint, brushColours, brushPos, brushSize, canvas, dispatchFn, eventDc, keyChar, keyCode, keyModifiers, mapPoint)
|
||||
|
@ -1 +0,0 @@
|
||||
.
|
1
requirements.txt
Symbolic link
1
requirements.txt
Symbolic link
@ -0,0 +1 @@
|
||||
assets/text/requirements.txt
|
Loading…
Reference in New Issue
Block a user