Initial release sans tools.

This commit is contained in:
Lucio Andrés Illanes Albornoz 2018-01-07 16:43:41 +01:00
parent f6911293c3
commit 84ab4eee5a
12 changed files with 503 additions and 332 deletions

View File

@ -90,7 +90,7 @@ class IrcClient:
# {{{ queue(self, *args): Parse and queue single line to server from list
def queue(self, *args):
msg = ""; argNumMax = len(args);
for argNum in range(0, argNumMax):
for argNum in range(argNumMax):
if argNum == (argNumMax - 1):
msg += ":" + args[argNum]
else:

View File

@ -27,6 +27,7 @@ import os, sys, time
import json
import IrcClient
import requests, urllib.request
from MiRCARTCanvasStore import MiRCARTCanvasStore
from MiRCARTToPngFile import MiRCARTToPngFile
class IrcMiRCARTBot(IrcClient.IrcClient):
@ -139,7 +140,9 @@ class IrcMiRCARTBot(IrcClient.IrcClient):
self._log("Unknown URL type specified!")
self.queue("PRIVMSG", message[2], "4/!\\ Unknown URL type specified!")
return
MiRCARTToPngFile(asciiTmpFilePath, "DejaVuSansMono.ttf", 11).export(imgTmpFilePath)
canvasStore = MiRCARTCanvasStore(inFile=asciiTmpFilePath)
MiRCARTToPngFile(canvasStore.outMap, "DejaVuSansMono.ttf", 11).export(imgTmpFilePath)
imgurResponse = self._uploadToImgur(imgTmpFilePath, "MiRCART image", "MiRCART image", "c9a6efb3d7932fd")
if imgurResponse[0] == 200:
self._log("Uploaded as: {}".format(imgurResponse[1]))

View File

@ -23,40 +23,43 @@
#
from MiRCARTCanvasJournal import MiRCARTCanvasJournal
from MiRCARTCanvasStore import MiRCARTCanvasStore
from MiRCARTCanvasStore import MiRCARTCanvasStore, haveMiRCARTToPngFile, haveUrllib
from MiRCARTColours import MiRCARTColours
import wx
class MiRCARTCanvas(wx.Panel):
"""XXX"""
parentFrame = None
canvasPos = canvasSize = canvasWinSize = cellPos = cellSize = None
canvasPos = canvasSize = canvasWinSize = cellSize = None
canvasBitmap = canvasMap = canvasTools = None
mircBg = mircFg = mircBrushes = mircPens = None
brushColours = brushPos = brushSize = None
mircBrushes = mircPens = None
canvasJournal = canvasStore = None
# {{{ _initBrushesAndPens(self): XXX
def _initBrushesAndPens(self):
self.mircBrushes = [None for x in range(len(MiRCARTColours))]
self.mircPens = [None for x in range(len(MiRCARTColours))]
for mircColour in range(0, len(MiRCARTColours)):
for mircColour in range(len(MiRCARTColours)):
self.mircBrushes[mircColour] = wx.Brush( \
wx.Colour(MiRCARTColours[mircColour]), wx.BRUSHSTYLE_SOLID)
wx.Colour(MiRCARTColours[mircColour][0:4]), wx.BRUSHSTYLE_SOLID)
self.mircPens[mircColour] = wx.Pen( \
wx.Colour(MiRCARTColours[mircColour]), 1)
wx.Colour(MiRCARTColours[mircColour][0:4]), 1)
# }}}
# {{{ _drawPatch(self, patch, eventDc, tmpDc, atPoint): XXX
def _drawPatch(self, patch, eventDc, tmpDc, atPoint):
absPoint = self._relMapPointToAbsPoint((patch[0], patch[1]), atPoint)
if patch[4] == " ":
brushFg = self.mircBrushes[patch[3]]; brushBg = self.mircBrushes[patch[3]];
pen = self.mircPens[patch[3]]
absPoint = self._relMapPointToAbsPoint(patch[0], atPoint)
if patch[3] == " ":
brushFg = self.mircBrushes[patch[1][1]]
brushBg = self.mircBrushes[patch[1][0]]
pen = self.mircPens[patch[1][1]]
else:
brushFg = self.mircBrushes[patch[2]]; brushBg = self.mircBrushes[patch[3]];
pen = self.mircPens[patch[2]]
brushFg = self.mircBrushes[patch[1][0]]
brushBg = self.mircBrushes[patch[1][1]]
pen = self.mircPens[patch[1][0]]
for dc in (eventDc, tmpDc):
dc.SetBrush(brushFg); dc.SetBackground(brushBg); dc.SetPen(pen);
dc.DrawRectangle(absPoint[0], absPoint[1], self.cellSize[0], self.cellSize[1])
dc.DrawRectangle(*absPoint, *self.cellSize)
# }}}
# {{{ _eventPointToMapPoint(self, eventPoint): XXX
def _eventPointToMapPoint(self, eventPoint):
@ -72,13 +75,11 @@ class MiRCARTCanvas(wx.Panel):
# }}}
# {{{ _relMapPointToAbsPoint(self, relMapPoint, atPoint): XXX
def _relMapPointToAbsPoint(self, relMapPoint, atPoint):
absX = (atPoint[0] + relMapPoint[0]) * self.cellSize[0]
absY = (atPoint[1] + relMapPoint[1]) * self.cellSize[1]
return (absX, absY)
return [(a+b)*c for a,b,c in zip(atPoint, relMapPoint, self.cellSize)]
# }}}
# {{{ _setMapCell(self, absMapPoint, colourFg, colourBg, char): XXX
def _setMapCell(self, absMapPoint, colourFg, colourBg, char):
self.canvasMap[absMapPoint[1]][absMapPoint[0]] = [colourFg, colourBg, char]
# {{{ _setMapCell(self, absMapPoint, colours, charAttrs, char): XXX
def _setMapCell(self, absMapPoint, colours, charAttrs, char):
self.canvasMap[absMapPoint[1]][absMapPoint[0]] = [colours, charAttrs, char]
# }}}
# {{{ onClose(self, event): XXX
@ -86,17 +87,24 @@ class MiRCARTCanvas(wx.Panel):
self.Destroy(); self.__del__();
# }}}
# {{{ onJournalUpdate(self, isTmp, absMapPoint, patch, eventDc, tmpDc, atPoint):
def onJournalUpdate(self, isTmp, absMapPoint, patch, eventDc, tmpDc, atPoint):
def onJournalUpdate(self, isTmp, absMapPoint, patch, eventDc, tmpDc, atPoint, isInherit=False):
if eventDc == None:
eventDc = wx.ClientDC(self); tmpDc = wx.MemoryDC();
if tmpDc == None:
tmpDc.SelectObject(self.canvasBitmap)
if isTmp == True:
if isInherit:
patch[1:] = self._getMapCell(patch[0])
self._drawPatch(patch, eventDc, tmpDc, atPoint)
else:
self._setMapCell(absMapPoint, *patch[2:5])
if isInherit:
patchOld = patch.copy()
patchOld[1:] = self._getMapCell(patchOld[0])
self._setMapCell(absMapPoint, *patch[1:])
self._drawPatch(patch, eventDc, tmpDc, atPoint)
self.parentFrame.onCanvasUpdate()
if isInherit:
return patchOld
# }}}
# {{{ onMouseEvent(self, event): XXX
def onMouseEvent(self, event):
@ -106,14 +114,58 @@ class MiRCARTCanvas(wx.Panel):
eventPoint = event.GetLogicalPosition(eventDc)
mapPoint = self._eventPointToMapPoint(eventPoint)
for tool in self.canvasTools:
mapPatches = tool.onMouseEvent(event, mapPoint, event.Dragging(), \
event.LeftIsDown(), event.RightIsDown())
mapPatches = tool.onMouseEvent( \
event, mapPoint, self.brushColours, self.brushSize, \
event.Dragging(), event.LeftIsDown(), event.RightIsDown())
self.canvasJournal.merge(mapPatches, eventDc, tmpDc, mapPoint)
self.parentFrame.onCanvasMotion(event, mapPoint)
# }}}
# {{{ onMouseWindowEvent(self, event): XXX
def onMouseWindowEvent(self, event):
eventObject = event.GetEventObject()
eventDc = wx.ClientDC(self); tmpDc = wx.MemoryDC();
tmpDc.SelectObject(self.canvasBitmap)
self.canvasJournal.resetCursor(eventDc, tmpDc)
self.parentFrame.onCanvasMotion(event)
# }}}
# {{{ onPaint(self, event): XXX
def onPaint(self, event):
eventDc = wx.BufferedPaintDC(self, self.canvasBitmap)
# }}}
# {{{ onStoreUpdate(self, newCanvasSize, newCanvas=None):
def onStoreUpdate(self, newCanvasSize, newCanvas=None):
if newCanvasSize != None:
self.resize(newCanvasSize)
self.canvasJournal.reset()
if newCanvas != None:
self.canvasMap = newCanvas.copy()
for numRow in range(self.canvasSize[1]):
numRowCols = len(self.canvasMap[numRow])
if numRowCols < self.canvasSize[0]:
colsDelta = self.canvasSize[0] - numRowCols
self.canvasMap[numRow][self.canvasSize[0]:] = \
[[(1, 1), 0, " "] for y in range(colsDelta)]
else:
del self.canvasMap[numRow][self.canvasSize[0]:]
else:
self.canvasMap = [[[(1, 1), 0, " "] \
for x in range(self.canvasSize[0])] \
for y in range(self.canvasSize[1])]
canvasWinSize = [a*b for a,b in zip(self.canvasSize, self.cellSize)]
if self.canvasBitmap != None:
self.canvasBitmap.Destroy()
self.canvasBitmap = wx.Bitmap(canvasWinSize)
eventDc = wx.ClientDC(self); tmpDc = wx.MemoryDC();
tmpDc.SelectObject(self.canvasBitmap)
for numRow in range(self.canvasSize[1]):
for numCol in range(self.canvasSize[0]):
self.onJournalUpdate(False, \
(numCol, numRow), \
[(numCol, numRow), \
*self.canvasMap[numRow][numCol]], \
eventDc, tmpDc, (0, 0))
wx.SafeYield()
# }}}
# {{{ redo(self): XXX
def redo(self):
return self.canvasJournal.redo()
@ -124,12 +176,12 @@ class MiRCARTCanvas(wx.Panel):
self.SetSize(*self.canvasPos, \
newCanvasSize[0] * self.cellSize[0], \
newCanvasSize[1] * self.cellSize[1])
for numRow in range(0, self.canvasSize[1]):
for numRow in range(self.canvasSize[1]):
for numNewCol in range(self.canvasSize[0], newCanvasSize[0]):
self.canvasMap[numRow].append([1, 1, " "])
for numNewRow in range(self.canvasSize[1], newCanvasSize[1]):
self.canvasMap.append([])
for numNewCol in range(0, newCanvasSize[0]):
for numNewCol in range(newCanvasSize[0]):
self.canvasMap[numNewRow].append([1, 1, " "])
self.canvasSize = newCanvasSize
canvasWinSize = ( \
@ -162,14 +214,16 @@ class MiRCARTCanvas(wx.Panel):
self.canvasTools = [canvasTool(self) for canvasTool in canvasTools]
self.cellSize = cellSize
self.cellPos = (0, 0)
self.mircBg = 1; self.mircFg = 4; self._initBrushesAndPens();
self.brushColours = [4, 1]; self._initBrushesAndPens();
self.brushPos = [0, 0]; self.brushSize = [1, 1];
self.canvasJournal = MiRCARTCanvasJournal(parentCanvas=self)
self.canvasStore = MiRCARTCanvasStore(parentCanvas=self)
super().__init__(parent, pos=canvasPos, \
size=[w*h for w,h in zip(canvasSize, cellSize)])
self.Bind(wx.EVT_CLOSE, self.onClose)
self.Bind(wx.EVT_ENTER_WINDOW, self.onMouseWindowEvent)
self.Bind(wx.EVT_LEAVE_WINDOW, self.onMouseWindowEvent)
self.Bind(wx.EVT_LEFT_DOWN, self.onMouseEvent)
self.Bind(wx.EVT_MOTION, self.onMouseEvent)
self.Bind(wx.EVT_PAINT, self.onPaint)

View File

@ -31,28 +31,26 @@ class MiRCARTCanvasJournal():
def _popTmp(self, eventDc, tmpDc):
if self.patchesTmp:
for patch in self.patchesTmp:
patch[2:] = self.parentCanvas._getMapCell([patch[0], patch[1]])
self.parentCanvas.onJournalUpdate(True, \
(patch[0:2]), patch, eventDc, tmpDc, (0, 0))
self.parentCanvas.onJournalUpdate(True, \
patch[0], patch, eventDc, tmpDc, (0, 0), True)
self.patchesTmp = []
# }}}
# {{{ _pushTmp(self, atPoint, patch): XXX
def _pushTmp(self, absMapPoint):
self.patchesTmp.append([*absMapPoint, None, None, None])
self.patchesTmp.append([absMapPoint, None, None, None])
# }}}
# {{{ _pushUndo(self, atPoint, patch): XXX
def _pushUndo(self, atPoint, patch, mapItem):
# {{{ _pushUndo(self, atPoint, patchUndo, patchRedo): XXX
def _pushUndo(self, atPoint, patchUndo, patchRedo):
if self.patchesUndoLevel > 0:
del self.patchesUndo[0:self.patchesUndoLevel]
self.patchesUndoLevel = 0
absMapPoint = self._relMapPointToAbsMapPoint((patch[0], patch[1]), atPoint)
self.patchesUndo.insert(0, ( \
(absMapPoint[0], absMapPoint[1], mapItem[0], mapItem[1], mapItem[2]), \
(absMapPoint[0], absMapPoint[1], patch[2], patch[3], patch[4])))
absMapPoint = self._relMapPointToAbsMapPoint(patchUndo[0], atPoint)
self.patchesUndo.insert(0, [ \
[absMapPoint, *patchUndo[1:]], [absMapPoint, *patchRedo[1:]]])
# }}}
# {{{ _relMapPointToAbsMapPoint(self, relMapPoint, atPoint): XXX
def _relMapPointToAbsMapPoint(self, relMapPoint, atPoint):
return (atPoint[0] + relMapPoint[0], atPoint[1] + relMapPoint[1])
return [a+b for a,b in zip(atPoint, relMapPoint)]
# }}}
# {{{ merge(self, mapPatches, eventDc, tmpDc, atPoint): XXX
def merge(self, mapPatches, eventDc, tmpDc, atPoint):
@ -61,40 +59,45 @@ class MiRCARTCanvasJournal():
if mapPatchTmp:
self._popTmp(eventDc, tmpDc)
for patch in mapPatch[1]:
absMapPoint = self._relMapPointToAbsMapPoint(patch[0:2], atPoint)
mapItem = self.parentCanvas._getMapCell(absMapPoint)
absMapPoint = self._relMapPointToAbsMapPoint(patch[0], atPoint)
if mapPatchTmp:
self._pushTmp(absMapPoint)
self.parentCanvas.onJournalUpdate(mapPatchTmp, \
absMapPoint, patch, eventDc, tmpDc, atPoint)
elif mapItem != patch[2:5]:
self._pushUndo(atPoint, patch, mapItem)
self.parentCanvas.onJournalUpdate(mapPatchTmp, \
self.parentCanvas.onJournalUpdate(mapPatchTmp, \
absMapPoint, patch, eventDc, tmpDc, atPoint)
else:
patchUndo = \
self.parentCanvas.onJournalUpdate(mapPatchTmp, \
absMapPoint, patch, eventDc, tmpDc, atPoint, True)
self._pushUndo(atPoint, patchUndo, patch)
# }}}
# {{{ redo(self): XXX
def redo(self):
if self.patchesUndoLevel > 0:
self.patchesUndoLevel -= 1
redoPatch = self.patchesUndo[self.patchesUndoLevel][1]
self.parentCanvas.onJournalUpdate(False, \
(redoPatch[0:2]), redoPatch, None, None, (0, 0))
self.parentCanvas.onJournalUpdate(False, \
redoPatch[0], redoPatch, None, None, (0, 0))
return True
else:
return False
# }}}
# {{{ reset(self): XXX
def reset(self):
self.patchesTmp = []
self.patchesUndo = [None]; self.patchesUndoLevel = 0;
self.patchesTmp = []; self.patchesUndo = [None]; self.patchesUndoLevel = 0;
# }}}
# {{{ resetCursor(self, eventDc, tmpDc): XXX
def resetCursor(self, eventDc, tmpDc):
if len(self.patchesTmp):
self._popTmp(eventDc, tmpDc)
self.patchesTmp = []
# }}}
# {{{ undo(self): XXX
def undo(self):
if self.patchesUndo[self.patchesUndoLevel] != None:
undoPatch = self.patchesUndo[self.patchesUndoLevel][0]
self.patchesUndoLevel += 1
self.parentCanvas.onJournalUpdate(False, \
(undoPatch[0:2]), undoPatch, None, None, (0, 0))
self.parentCanvas.onJournalUpdate(False, \
undoPatch[0], undoPatch, None, None, (0, 0))
return True
else:
return False

View File

@ -22,9 +22,13 @@
# SOFTWARE.
#
import base64
import io
import wx
try:
import wx
haveWx = True
except ImportError:
haveWx = False
try:
from MiRCARTToPngFile import MiRCARTToPngFile
@ -78,66 +82,59 @@ class MiRCARTCanvasStore():
return cellState | bit
# }}}
# {{{ exportPastebin(self, apiDevKey): XXX
def exportPastebin(self, apiDevKey):
# {{{ exportBitmapToPngFile(self, canvasBitmap, outPathName, outType): XXX
def exportBitmapToPngFile(self, canvasBitmap, outPathName, outType):
return canvasBitmap.ConvertToImage().SaveFile(outPathName, outType)
# }}}
# {{{ exportPastebin(self, apiDevKey, canvasMap, canvasSize, pasteName="", pastePrivate=0): XXX
def exportPastebin(self, apiDevKey, canvasMap, canvasSize, pasteName="", pastePrivate=0):
if haveUrllib:
outFile = io.StringIO(); self.exportTextFile(outFile);
requestData = { \
"api_dev_key": self.apiDevKey, \
"api_option": "paste", \
"api_paste_code": base64.b64encode(outFile.read()), \
"api_paste_name": pasteName, \
outFile = io.StringIO()
self.exportTextFile(canvasMap, canvasSize, outFile)
requestData = { \
"api_dev_key": apiDevKey, \
"api_option": "paste", \
"api_paste_code": outFile.getvalue().encode(), \
"api_paste_name": pasteName, \
"api_paste_private": pastePrivate}
responseHttp = requests.post("https://pastebin.com/post.php", \
responseHttp = requests.post("https://pastebin.com/api/api_post.php", \
data=requestData)
if responseHttp.status_code == 200:
return responseHttp.text
if responseHttp.text.startswith("http"):
return (True, responseHttp.text)
else:
return (False, responseHttp.text)
else:
return None
return (False, str(responseHttp.status_code))
else:
return None
return (False, "missing requests and/or urllib3 module(s)")
# }}}
# {{{ exportPngFile(self): XXX
def exportPngFile(self, pathName):
# {{{ exportPngFile(self, canvasMap, outPathName): XXX
def exportPngFile(self, canvasMap, outPathName):
if haveMiRCARTToPngFile:
outFile = io.StringIO(); self.exportTextFile(outFile);
MiRCARTToPng(outFile).export(pathName)
MiRCARTToPngFile(canvasMap).export(outPathName)
return True
else:
return False
# }}}
# {{{ exportTextFile(self, outFile): XXX
def exportTextFile(self, outFile):
canvasMap = self.parentCanvas.canvasMap
canvasSize = self.parentCanvas.canvasSize
for canvasRow in range(0, canvasSize[1]):
# {{{ exportTextFile(self, canvasMap, canvasSize, outFile): XXX
def exportTextFile(self, canvasMap, canvasSize, outFile):
for canvasRow in range(canvasSize[1]):
canvasLastColours = []
for canvasCol in range(0, canvasSize[0]):
canvasColColours = canvasMap[canvasRow][canvasCol][0:2]
canvasColText = self.canvasMap[canvasRow][canvasCol][2]
if canvasColColours != canvasLastColours:
canvasLastColours = canvasColColours
outFile.write("\x03" + \
str(canvasColColours[0]) + \
"," + str(canvasColColours[1]))
for canvasCol in range(canvasSize[0]):
canvasColColours = canvasMap[canvasRow][canvasCol][0]
canvasColText = canvasMap[canvasRow][canvasCol][2]
if canvasColColours != canvasLastColours:
canvasLastColours = canvasColColours
outFile.write("\x03" + \
str(canvasColColours[0]) + \
"," + str(canvasColColours[1]))
outFile.write(canvasColText)
outFile.write("\n")
# }}}
# {{{ importIntoPanel(self): XXX
def importIntoPanel(self):
canvasSize = self.inSize; self.parentCanvas.resize(canvasSize);
self.parentCanvas.canvasJournal.reset()
eventDc = wx.ClientDC(self.parentCanvas); tmpDc = wx.MemoryDC();
tmpDc.SelectObject(self.parentCanvas.canvasBitmap)
for numRow in range(0, len(self.outMap)):
for numCol in range(0, len(self.outMap[numRow])):
self.parentCanvas.onJournalUpdate(False, \
(numCol, numRow), [numCol, numRow, \
self.outMap[numRow][numCol][0][0], \
self.outMap[numRow][numCol][0][1], \
self.outMap[numRow][numCol][2]], \
eventDc, tmpDc, (0, 0))
wx.SafeYield()
self.parentCanvas.onStoreUpdate(self.inSize, self.outMap)
# }}}
# {{{ importTextFile(self, pathName): XXX
def importTextFile(self, pathName):
@ -210,26 +207,7 @@ class MiRCARTCanvasStore():
# }}}
# {{{ importNew(self, newCanvasSize=None): XXX
def importNew(self, newCanvasSize=None):
if newCanvasSize != None:
self.parentCanvas.resize(newCanvasSize)
self.parentCanvas.canvasJournal.reset()
self.parentCanvas.canvasMap = [[[1, 1, " "] \
for x in range(self.parentCanvas.canvasSize[0])] \
for y in range(self.parentCanvas.canvasSize[1])]
canvasWinSize = ( \
self.parentCanvas.cellSize[0] * self.parentCanvas.canvasSize[0], \
self.parentCanvas.cellSize[1] * self.parentCanvas.canvasSize[1])
if self.parentCanvas.canvasBitmap != None:
self.parentCanvas.canvasBitmap.Destroy()
self.parentCanvas.canvasBitmap = wx.Bitmap(canvasWinSize)
eventDc = wx.ClientDC(self.parentCanvas); tmpDc = wx.MemoryDC();
tmpDc.SelectObject(self.parentCanvas.canvasBitmap)
for numRow in range(0, len(self.parentCanvas.canvasMap)):
for numCol in range(0, len(self.parentCanvas.canvasMap[numRow])):
self.parentCanvas.onJournalUpdate(False, \
(numCol, numRow), [numCol, numRow, 1, 1, " "], \
eventDc, tmpDc, (0, 0))
wx.SafeYield()
self.parentCanvas.onStoreUpdate(newCanvasSize)
# }}}
#

View File

@ -23,25 +23,25 @@
#
#
# MiRCARTColours: mIRC colour number to RGBA map given none of ^[BFV_] (bold, italic, reverse, underline)
# MiRCARTColours: mIRC colour number to RGBA map given none of ^[BFV_] (bold, italic, reverse, underline],
#
MiRCARTColours = [
(255, 255, 255, 255), # White
(0, 0, 0, 255), # Black
(0, 0, 187, 255), # Blue
(0, 187, 0, 255), # Green
(255, 85, 85, 255), # Light Red
(187, 0, 0, 255), # Red
(187, 0, 187, 255), # Purple
(187, 187, 0, 255), # Yellow
(255, 255, 85, 255), # Light Yellow
(85, 255, 85, 255), # Light Green
(0, 187, 187, 255), # Cyan
(85, 255, 255, 255), # Light Cyan
(85, 85, 255, 255), # Light Blue
(255, 85, 255, 255), # Pink
(85, 85, 85, 255), # Grey
(187, 187, 187, 255), # Light Grey
[255, 255, 255, 255, "White"],
[0, 0, 0, 255, "Black"],
[0, 0, 187, 255, "Blue"],
[0, 187, 0, 255, "Green"],
[255, 85, 85, 255, "Light Red"],
[187, 0, 0, 255, "Red"],
[187, 0, 187, 255, "Purple"],
[187, 187, 0, 255, "Yellow"],
[255, 255, 85, 255, "Light Yellow"],
[85, 255, 85, 255, "Light Green"],
[0, 187, 187, 255, "Cyan"],
[85, 255, 255, 255, "Light Cyan"],
[85, 85, 255, 255, "Light Blue"],
[255, 85, 255, 255, "Pink"],
[85, 85, 85, 255, "Grey"],
[187, 187, 187, 255, "Light Grey"],
]
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -22,61 +22,59 @@
# SOFTWARE.
#
from MiRCARTCanvas import MiRCARTCanvas
from MiRCARTCanvas import MiRCARTCanvas, haveUrllib
from MiRCARTColours import MiRCARTColours
from MiRCARTGeneralFrame import MiRCARTGeneralFrame, \
TID_COMMAND, TID_MENU, TID_NOTHING, TID_SELECT, TID_TOOLBAR, TID_ACCELS
import os, wx
class MiRCARTFrame(wx.Frame):
class MiRCARTFrame(MiRCARTGeneralFrame):
"""XXX"""
panelSkin = panelCanvas = canvasPathName = None
panelCanvas = canvasPathName = None
canvasPos = canvasSize = canvasTools = cellSize = None
menuItemsById = menuBar = toolBar = accelTable = statusBar = None
# {{{ Types
TID_COMMAND = (0x001)
TID_NOTHING = (0x002)
TID_MENU = (0x003)
TID_SELECT = (0x004)
TID_TOOLBAR = (0x005)
TID_ACCELS = (0x006)
# }}}
# {{{ Commands
# Id Type Id Labels Icon bitmap Accelerator [Initial state]
CID_NEW = (0x100, TID_COMMAND, "New", "&New", [wx.ART_NEW], None)
CID_OPEN = (0x101, TID_COMMAND, "Open", "&Open", [wx.ART_FILE_OPEN], None)
CID_SAVE = (0x102, TID_COMMAND, "Save", "&Save", [wx.ART_FILE_SAVE], None)
CID_SAVEAS = (0x103, TID_COMMAND, "Save As...", "Save &As...", [wx.ART_FILE_SAVE_AS], None)
CID_EXPORT_AS_PNG = (0x104, TID_COMMAND, "Export as PNG...", "Export as PN&G...", (), None, False)
CID_EXPORT_PASTEBIN = (0x105, TID_COMMAND, "Export to Pastebin...", "Export to Pasteb&in...", (), None, False)
CID_EXIT = (0x106, TID_COMMAND, "Exit", "E&xit", (), None)
CID_UNDO = (0x107, TID_COMMAND, "Undo", "&Undo", [wx.ART_UNDO], (wx.ACCEL_CTRL, ord("Z")), False)
CID_REDO = (0x108, TID_COMMAND, "Redo", "&Redo", [wx.ART_REDO], (wx.ACCEL_CTRL, ord("Y")), False)
CID_CUT = (0x109, TID_COMMAND, "Cut", "Cu&t", [wx.ART_CUT], None, False)
CID_COPY = (0x10a, TID_COMMAND, "Copy", "&Copy", [wx.ART_COPY], None, False)
CID_PASTE = (0x10b, TID_COMMAND, "Paste", "&Paste", [wx.ART_PASTE], None, False)
CID_DELETE = (0x10c, TID_COMMAND, "Delete", "De&lete", [wx.ART_DELETE], None, False)
CID_INCRBRUSH = (0x10d, TID_COMMAND, "Increase brush size", "&Increase brush size", [wx.ART_PLUS], None)
CID_DECRBRUSH = (0x10e, TID_COMMAND, "Decrease brush size", "&Decrease brush size", [wx.ART_MINUS], None)
CID_SOLID_BRUSH = (0x10f, TID_SELECT, "Solid brush", "&Solid brush", [None], None, True)
CID_RECT = (0x110, TID_SELECT, "Rectangle", "&Rectangle", [None], None, True)
CID_CIRCLE = (0x111, TID_SELECT, "Circle", "&Circle", [None], None, False)
CID_LINE = (0x112, TID_SELECT, "Line", "&Line", [None], None, False)
CID_COLOUR00 = (0x113, TID_COMMAND, "Colour #00", "Colour #00", MiRCARTColours[0], None)
CID_COLOUR01 = (0x114, TID_COMMAND, "Colour #01", "Colour #01", MiRCARTColours[1], None)
CID_COLOUR02 = (0x115, TID_COMMAND, "Colour #02", "Colour #02", MiRCARTColours[2], None)
CID_COLOUR03 = (0x116, TID_COMMAND, "Colour #03", "Colour #03", MiRCARTColours[3], None)
CID_COLOUR04 = (0x117, TID_COMMAND, "Colour #04", "Colour #04", MiRCARTColours[4], None)
CID_COLOUR05 = (0x118, TID_COMMAND, "Colour #05", "Colour #05", MiRCARTColours[5], None)
CID_COLOUR06 = (0x119, TID_COMMAND, "Colour #06", "Colour #06", MiRCARTColours[6], None)
CID_COLOUR07 = (0x11a, TID_COMMAND, "Colour #07", "Colour #07", MiRCARTColours[7], None)
CID_COLOUR08 = (0x11b, TID_COMMAND, "Colour #08", "Colour #08", MiRCARTColours[8], None)
CID_COLOUR09 = (0x11c, TID_COMMAND, "Colour #09", "Colour #09", MiRCARTColours[9], None)
CID_COLOUR10 = (0x11d, TID_COMMAND, "Colour #10", "Colour #10", MiRCARTColours[10], None)
CID_COLOUR11 = (0x11e, TID_COMMAND, "Colour #11", "Colour #11", MiRCARTColours[11], None)
CID_COLOUR12 = (0x11f, TID_COMMAND, "Colour #12", "Colour #12", MiRCARTColours[12], None)
CID_COLOUR13 = (0x120, TID_COMMAND, "Colour #13", "Colour #13", MiRCARTColours[13], None)
CID_COLOUR14 = (0x121, TID_COMMAND, "Colour #14", "Colour #14", MiRCARTColours[14], None)
CID_COLOUR15 = (0x122, TID_COMMAND, "Colour #15", "Colour #15", MiRCARTColours[15], None)
CID_NEW = (0x100, TID_COMMAND, "New", "&New", wx.ART_NEW, (wx.ACCEL_CTRL, ord("N")))
CID_OPEN = (0x101, TID_COMMAND, "Open", "&Open", wx.ART_FILE_OPEN, (wx.ACCEL_CTRL, ord("O")))
CID_SAVE = (0x102, TID_COMMAND, "Save", "&Save", wx.ART_FILE_SAVE, (wx.ACCEL_CTRL, ord("S")))
CID_SAVEAS = (0x103, TID_COMMAND, "Save As...", "Save &As...", wx.ART_FILE_SAVE_AS, None)
CID_EXPORT_AS_PNG = (0x104, TID_COMMAND, "Export as PNG...", \
"Export as PN&G...", None, None)
CID_EXPORT_PASTEBIN = (0x105, TID_COMMAND, "Export to Pastebin...", \
"Export to Pasteb&in...", None, None, haveUrllib)
CID_EXIT = (0x106, TID_COMMAND, "Exit", "E&xit", None, None)
CID_UNDO = (0x107, TID_COMMAND, "Undo", "&Undo", wx.ART_UNDO, (wx.ACCEL_CTRL, ord("Z")), False)
CID_REDO = (0x108, TID_COMMAND, "Redo", "&Redo", wx.ART_REDO, (wx.ACCEL_CTRL, ord("Y")), False)
CID_CUT = (0x109, TID_COMMAND, "Cut", "Cu&t", wx.ART_CUT, None, False)
CID_COPY = (0x10a, TID_COMMAND, "Copy", "&Copy", wx.ART_COPY, None, False)
CID_PASTE = (0x10b, TID_COMMAND, "Paste", "&Paste", wx.ART_PASTE, None, False)
CID_DELETE = (0x10c, TID_COMMAND, "Delete", "De&lete", wx.ART_DELETE, None, False)
CID_INCRBRUSH = (0x10d, TID_COMMAND, "Increase brush size", \
"&Increase brush size", wx.ART_PLUS, None)
CID_DECRBRUSH = (0x10e, TID_COMMAND, "Decrease brush size", \
"&Decrease brush size", wx.ART_MINUS, None)
CID_SOLID_BRUSH = (0x10f, TID_SELECT, "Solid brush", "&Solid brush", None, None, True)
CID_RECT = (0x110, TID_SELECT, "Rectangle", "&Rectangle", None, None, True)
CID_CIRCLE = (0x111, TID_SELECT, "Circle", "&Circle", None, None, False)
CID_LINE = (0x112, TID_SELECT, "Line", "&Line", None, None, False)
CID_COLOUR00 = (0x113, TID_COMMAND, "Colour #00", "Colour #00", None, None)
CID_COLOUR01 = (0x114, TID_COMMAND, "Colour #01", "Colour #01", None, None)
CID_COLOUR02 = (0x115, TID_COMMAND, "Colour #02", "Colour #02", None, None)
CID_COLOUR03 = (0x116, TID_COMMAND, "Colour #03", "Colour #03", None, None)
CID_COLOUR04 = (0x117, TID_COMMAND, "Colour #04", "Colour #04", None, None)
CID_COLOUR05 = (0x118, TID_COMMAND, "Colour #05", "Colour #05", None, None)
CID_COLOUR06 = (0x119, TID_COMMAND, "Colour #06", "Colour #06", None, None)
CID_COLOUR07 = (0x11a, TID_COMMAND, "Colour #07", "Colour #07", None, None)
CID_COLOUR08 = (0x11b, TID_COMMAND, "Colour #08", "Colour #08", None, None)
CID_COLOUR09 = (0x11c, TID_COMMAND, "Colour #09", "Colour #09", None, None)
CID_COLOUR10 = (0x11d, TID_COMMAND, "Colour #10", "Colour #10", None, None)
CID_COLOUR11 = (0x11e, TID_COMMAND, "Colour #11", "Colour #11", None, None)
CID_COLOUR12 = (0x11f, TID_COMMAND, "Colour #12", "Colour #12", None, None)
CID_COLOUR13 = (0x120, TID_COMMAND, "Colour #13", "Colour #13", None, None)
CID_COLOUR14 = (0x121, TID_COMMAND, "Colour #14", "Colour #14", None, None)
CID_COLOUR15 = (0x122, TID_COMMAND, "Colour #15", "Colour #15", None, None)
# }}}
# {{{ Non-items
NID_MENU_SEP = (0x200, TID_NOTHING)
@ -107,79 +105,61 @@ class MiRCARTFrame(wx.Frame):
CID_COLOUR15))
# }}}
# {{{ Accelerators (hotkeys)
AID_EDIT = (0x500, TID_ACCELS, (CID_UNDO, CID_REDO))
AID_EDIT = (0x500, TID_ACCELS, ( \
CID_NEW, CID_OPEN, CID_SAVE, CID_UNDO, CID_REDO))
# }}}
# {{{ _drawIcon(self, solidColour): XXX
def _drawIcon(self, solidColour):
iconBitmap = wx.Bitmap((16,16))
iconDc = wx.MemoryDC(); iconDc.SelectObject(iconBitmap);
iconBrush = wx.Brush(wx.Colour(solidColour), wx.BRUSHSTYLE_SOLID)
iconDc.SetBrush(iconBrush); iconDc.SetBackground(iconBrush);
iconDc.SetPen(wx.Pen(wx.Colour(solidColour), 1))
iconDc.DrawRectangle(0, 0, 16, 16)
return iconBitmap
# {{{ _dialogSaveChanges(self)
def _dialogSaveChanges(self):
with wx.MessageDialog(self, \
"Do you want to save changes to {}?".format( \
self.canvasPathName), "MiRCART", \
wx.CANCEL|wx.CANCEL_DEFAULT|wx.ICON_QUESTION|wx.YES_NO) as dialog:
dialogChoice = dialog.ShowModal()
return dialogChoice
# }}}
# {{{ _initAccelTable(self, accelsDescr, handler): XXX
def _initAccelTable(self, accelsDescr, handler):
accelTableEntries = [wx.AcceleratorEntry() for n in range(0, len(accelsDescr[2]))]
for numAccel in range(0, len(accelsDescr[2])):
accelDescr = accelsDescr[2][numAccel]
if accelDescr[5] != None:
accelTableEntries[numAccel].Set(accelDescr[5][0], accelDescr[5][1], accelDescr[0])
self.Bind(wx.EVT_MENU, handler, id=accelDescr[0])
return accelTableEntries
# {{{ _setPaletteToolBitmaps(self): XXX
def _setPaletteToolBitmaps(self):
paletteDescr = ( \
self.CID_COLOUR00, self.CID_COLOUR01, self.CID_COLOUR02, self.CID_COLOUR03, self.CID_COLOUR04, \
self.CID_COLOUR05, self.CID_COLOUR06, self.CID_COLOUR07, self.CID_COLOUR08, self.CID_COLOUR09, \
self.CID_COLOUR10, self.CID_COLOUR11, self.CID_COLOUR12, self.CID_COLOUR13, self.CID_COLOUR14, \
self.CID_COLOUR15)
for numColour in range(len(paletteDescr)):
toolBitmapColour = MiRCARTColours[numColour][0:4]
toolBitmap = wx.Bitmap((16,16))
toolBitmapDc = wx.MemoryDC(); toolBitmapDc.SelectObject(toolBitmap);
toolBitmapBrush = wx.Brush( \
wx.Colour(toolBitmapColour), wx.BRUSHSTYLE_SOLID)
toolBitmapDc.SetBrush(toolBitmapBrush)
toolBitmapDc.SetBackground(toolBitmapBrush)
toolBitmapDc.SetPen(wx.Pen(wx.Colour(toolBitmapColour), 1))
toolBitmapDc.DrawRectangle(0, 0, 16, 16)
self.toolBar.SetToolNormalBitmap( \
paletteDescr[numColour][0], toolBitmap)
# }}}
# {{{ _initMenus(self, menuBar, menusDescr, handler): XXX
def _initMenus(self, menuBar, menusDescr, handler):
for menuDescr in menusDescr:
menuWindow = wx.Menu()
for menuItem in menuDescr[4]:
if menuItem == self.NID_MENU_SEP:
menuWindow.AppendSeparator()
elif menuItem[1] == self.TID_SELECT:
menuItemWindow = menuWindow.AppendRadioItem(menuItem[0], menuItem[3], menuItem[2])
self.menuItemsById[menuItem[0]] = menuItemWindow
self.Bind(wx.EVT_MENU, handler, menuItemWindow)
if len(menuItem) == 7:
menuItemWindow.Check(menuItem[6])
else:
menuItemWindow = menuWindow.Append(menuItem[0], menuItem[3], menuItem[2])
self.menuItemsById[menuItem[0]] = menuItemWindow
self.Bind(wx.EVT_MENU, handler, menuItemWindow)
if len(menuItem) == 7:
menuItemWindow.Enable(menuItem[6])
menuBar.Append(menuWindow, menuDescr[3])
# }}}
# {{{ _initToolBars(self, toolBar, toolBarsDescr, handler): XXX
def _initToolBars(self, toolBar, toolBarsDescr, handler):
for toolBarDescr in toolBarsDescr:
for toolBarItem in toolBarDescr[2]:
if toolBarItem == self.NID_TOOLBAR_SEP:
toolBar.AddSeparator()
else:
if len(toolBarItem[4]) == 4:
toolBarItemIcon = self._drawIcon(toolBarItem[4])
elif len(toolBarItem[4]) == 1 \
and toolBarItem[4][0] != None:
toolBarItemIcon = wx.ArtProvider.GetBitmap( \
toolBarItem[4][0], wx.ART_TOOLBAR, (16,16))
else:
toolBarItemIcon = wx.ArtProvider.GetBitmap( \
wx.ART_HELP, wx.ART_TOOLBAR, (16,16))
toolBarItemWindow = self.toolBar.AddTool( \
toolBarItem[0], toolBarItem[2], toolBarItemIcon)
self.Bind(wx.EVT_TOOL, handler, toolBarItemWindow)
self.Bind(wx.EVT_TOOL_RCLICKED, handler, toolBarItemWindow)
# }}}
# {{{ _updateStatusBar(self): XXX
def _updateStatusBar(self):
text = "Foreground colour:"
text += " " + str(self.panelCanvas.mircFg)
text += " | "
text += "Background colour:"
text += " " + str(self.panelCanvas.mircBg)
self.statusBar.SetStatusText(text)
# {{{ _updateStatusBar(self, showColours=None, showFileName=True, showPos=None): XXX
def _updateStatusBar(self, showColours=True, showFileName=True, showPos=True):
if showColours == True:
showColours = self.panelCanvas.brushColours
if showPos == True:
showPos = self.panelCanvas.brushPos
if showFileName == True:
showFileName = self.canvasPathName
textItems = []
if showPos != None:
textItems.append("X: {:03d} Y: {:03d}".format( \
showPos[0], showPos[1]))
if showColours != None:
textItems.append("FG: {:02d}, BG: {:02d}".format( \
showColours[0],showColours[1]))
textItems.append("{} on {}".format( \
MiRCARTColours[showColours[0]][4], \
MiRCARTColours[showColours[1]][4]))
if showFileName != None:
textItems.append("Current file: {}".format( \
os.path.basename(showFileName)))
self.statusBar.SetStatusText(" | ".join(textItems))
# }}}
# {{{ canvasExportAsPng(self): XXX
@ -189,31 +169,57 @@ class MiRCARTFrame(wx.Frame):
if dialog.ShowModal() == wx.ID_CANCEL:
return False
else:
try:
outPathName = dialog.GetPath()
self.panelCanvas.exportPngFile(outhPathName)
return True
except IOError as error:
pass
outPathName = dialog.GetPath()
self.panelCanvas.canvasStore.exportBitmapToPngFile( \
self.panelCanvas.canvasBitmap, outPathName, \
wx.BITMAP_TYPE_PNG)
return True
# }}}
# {{{ canvasExportPastebin(self): XXX
def canvasExportPastebin(self):
try:
self.panelCanvas.exportPastebin("")
return True
except IOError as error:
pass
pasteStatus, pasteResult = \
self.panelCanvas.canvasStore.exportPastebin( \
"", \
self.panelCanvas.canvasMap, \
self.panelCanvas.canvasSize)
if pasteStatus:
if not wx.TheClipboard.IsOpened():
wx.TheClipboard.Open()
wx.TheClipboard.SetData(wx.TextDataObject(pasteResult))
wx.TheClipboard.Close()
wx.MessageBox("Exported to Pastebin: " + pasteResult, \
"Export to Pastebin", wx.OK|wx.ICON_INFORMATION)
else:
wx.MessageBox("Failed to export to Pastebin: " + pasteResult, \
"Export to Pastebin", wx.OK|wx.ICON_EXCLAMATION)
# }}}
# {{{ canvasNew(self, newCanvasSize=None): XXX
def canvasNew(self, newCanvasSize=None):
if self.canvasPathName != None:
saveChanges = self._dialogSaveChanges()
if saveChanges == wx.ID_CANCEL:
return
elif saveChanges == wx.ID_NO:
pass
elif saveChanges == wx.ID_YES:
self.canvasSave()
if newCanvasSize == None:
newCanvasSize = (100, 30)
self.panelCanvas.canvasStore.importNew(newCanvasSize)
self.canvasPathName = None
self._updateStatusBar(); self.onCanvasUpdate();
# }}}
# {{{ canvasOpen(self): XXX
def canvasOpen(self):
with wx.FileDialog(self, self.CID_OPEN[2], os.getcwd(), "", \
if self.canvasPathName != None:
saveChanges = self._dialogSaveChanges()
if saveChanges == wx.ID_CANCEL:
return
elif saveChanges == wx.ID_NO:
pass
elif saveChanges == wx.ID_YES:
self.canvasSave()
with wx.FileDialog(self, self.CID_OPEN[2], os.getcwd(), "", \
"*.txt", wx.FD_OPEN) as dialog:
if dialog.ShowModal() == wx.ID_CANCEL:
return False
@ -230,10 +236,13 @@ class MiRCARTFrame(wx.Frame):
if self.canvasSaveAs() == False:
return
try:
self.panelCanvas.exportTextFile(self.canvasPathName)
return True
with open(self.canvasPathName, "w") as outFile:
self.panelCanvas.canvasStore.exportTextFile( \
self.panelCanvas.canvasMap, \
self.panelCanvas.canvasSize, outFile)
return True
except IOError as error:
pass
return False
# }}}
# {{{ canvasSaveAs(self): XXX
def canvasSaveAs(self):
@ -243,22 +252,32 @@ class MiRCARTFrame(wx.Frame):
return False
else:
self.canvasPathName = dialog.GetPath()
return True
return self.canvasSave()
# }}}
# {{{ onCanvasMotion(self, event): XXX
def onCanvasMotion(self, event, mapPoint=None):
eventType = event.GetEventType()
if eventType == wx.wxEVT_ENTER_WINDOW:
pass
elif eventType == wx.wxEVT_MOTION:
self._updateStatusBar(showPos=mapPoint)
elif eventType == wx.wxEVT_LEAVE_WINDOW:
pass
# }}}
# {{{ onCanvasUpdate(self): XXX
def onCanvasUpdate(self):
if self.panelCanvas.canvasJournal.patchesUndo[self.panelCanvas.canvasJournal.patchesUndoLevel] != None:
self.menuItemsById[self.CID_UNDO[0]].Enable(True)
self.toolBar.EnableTool(self.CID_UNDO[0], True)
else:
self.menuItemsById[self.CID_UNDO[0]].Enable(False)
self.toolBar.EnableTool(self.CID_UNDO[0], False)
if self.panelCanvas.canvasJournal.patchesUndoLevel > 0:
self.menuItemsById[self.CID_REDO[0]].Enable(True)
self.toolBar.EnableTool(self.CID_REDO[0], True)
else:
self.menuItemsById[self.CID_REDO[0]].Enable(False)
# }}}
# {{{ onClose(self, event): XXX
def onClose(self, event):
self.Destroy(); self.__del__();
self.toolBar.EnableTool(self.CID_REDO[0], False)
# }}}
# {{{ onFrameCommand(self, event): XXX
def onFrameCommand(self, event):
@ -305,9 +324,9 @@ class MiRCARTFrame(wx.Frame):
and cid <= self.CID_COLOUR15[0]:
numColour = cid - self.CID_COLOUR00[0]
if event.GetEventType() == wx.wxEVT_TOOL:
self.panelCanvas.mircFg = numColour
self.panelCanvas.brushColours[0] = numColour
elif event.GetEventType() == wx.wxEVT_TOOL_RCLICKED:
self.panelCanvas.mircBg = numColour
self.panelCanvas.brushColours[1] = numColour
self._updateStatusBar()
# }}}
# {{{ __del__(self): destructor method
@ -319,32 +338,13 @@ class MiRCARTFrame(wx.Frame):
#
# __init__(self, parent, appSize=(800, 600), canvasPos=(25, 50), cellSize=(7, 14), canvasSize=(100, 30), canvasTools=[]): initialisation method
def __init__(self, parent, appSize=(800, 600), canvasPos=(25, 50), cellSize=(7, 14), canvasSize=(100, 30), canvasTools=[]):
super().__init__(parent, wx.ID_ANY, "MiRCART", size=appSize)
self.panelSkin = wx.Panel(self, wx.ID_ANY)
panelSkin = super().__init__(parent, wx.ID_ANY, "MiRCART", size=appSize)
self._setPaletteToolBitmaps()
self.canvasPos = canvasPos; self.cellSize = cellSize; self.canvasSize = canvasSize;
self.canvasPathName = None
self.menuItemsById = {}; self.menuBar = wx.MenuBar();
self._initMenus(self.menuBar, \
[self.MID_FILE, self.MID_EDIT, self.MID_TOOLS], self.onFrameCommand)
self.SetMenuBar(self.menuBar)
self.toolBar = wx.ToolBar(self.panelSkin, -1, \
style=wx.HORIZONTAL|wx.TB_FLAT|wx.TB_NODIVIDER)
self.toolBar.SetToolBitmapSize((16,16))
self._initToolBars(self.toolBar, [self.BID_TOOLBAR], self.onFrameCommand)
self.toolBar.Realize(); self.toolBar.Fit();
self.accelTable = wx.AcceleratorTable( \
self._initAccelTable(self.AID_EDIT, self.onFrameCommand))
self.SetAcceleratorTable(self.accelTable)
self.Bind(wx.EVT_CLOSE, self.onClose)
self.statusBar = self.CreateStatusBar();
self.SetFocus(); self.Show(True);
self.canvasTools = canvasTools
self.panelCanvas = MiRCARTCanvas(self.panelSkin, parentFrame=self, \
canvasPos=self.canvasPos, canvasSize=self.canvasSize, \
self.panelCanvas = MiRCARTCanvas(panelSkin, parentFrame=self, \
canvasPos=self.canvasPos, canvasSize=self.canvasSize, \
canvasTools=self.canvasTools, cellSize=self.cellSize)
self.canvasNew()

140
MiRCARTGeneralFrame.py Normal file
View File

@ -0,0 +1,140 @@
#!/usr/bin/env python3
#
# MiRCARTGeneralFrame.py -- XXX
# Copyright (c) 2018 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
import os, wx
#
# Types
TID_COMMAND = (0x001)
TID_MENU = (0x002)
TID_NOTHING = (0x003)
TID_SELECT = (0x004)
TID_TOOLBAR = (0x005)
TID_ACCELS = (0x006)
class MiRCARTGeneralFrame(wx.Frame):
"""XXX"""
menuItemsById = toolBarItemsById = None
statusBar = toolBar = None
# {{{ _initAccelTable(self, accelsDescr, handler): XXX
def _initAccelTable(self, accelsDescr, handler):
accelTableEntries = [wx.AcceleratorEntry() for n in range(len(accelsDescr[2]))]
for numAccel in range(len(accelsDescr[2])):
accelDescr = accelsDescr[2][numAccel]
if accelDescr[5] != None:
accelTableEntries[numAccel].Set(*accelDescr[5], accelDescr[0])
self.Bind(wx.EVT_MENU, handler, id=accelDescr[0])
return accelTableEntries
# }}}
# {{{ _initMenus(self, menuBar, menusDescr, handler): XXX
def _initMenus(self, menuBar, menusDescr, handler):
for menuDescr in menusDescr:
menuWindow = wx.Menu()
for menuItem in menuDescr[4]:
if menuItem == self.NID_MENU_SEP:
menuWindow.AppendSeparator()
elif menuItem[1] == TID_SELECT:
menuItemWindow = menuWindow.AppendRadioItem(menuItem[0], menuItem[3], menuItem[2])
self.menuItemsById[menuItem[0]] = menuItemWindow
self.Bind(wx.EVT_MENU, handler, menuItemWindow)
if len(menuItem) == 7:
menuItemWindow.Check(menuItem[6])
else:
menuItemWindow = menuWindow.Append(menuItem[0], menuItem[3], menuItem[2])
self.menuItemsById[menuItem[0]] = menuItemWindow
self.Bind(wx.EVT_MENU, handler, menuItemWindow)
if len(menuItem) == 7:
menuItemWindow.Enable(menuItem[6])
menuBar.Append(menuWindow, menuDescr[3])
# }}}
# {{{ _initToolBars(self, toolBar, toolBarsDescr, handler): XXX
def _initToolBars(self, toolBar, toolBarsDescr, handler):
for toolBarDescr in toolBarsDescr:
for toolBarItem in toolBarDescr[2]:
if toolBarItem == self.NID_TOOLBAR_SEP:
toolBar.AddSeparator()
else:
if toolBarItem[4] != None:
toolBarItemIcon = wx.ArtProvider.GetBitmap( \
toolBarItem[4], wx.ART_TOOLBAR, (16,16))
else:
toolBarItemIcon = wx.ArtProvider.GetBitmap( \
wx.ART_HELP, wx.ART_TOOLBAR, (16,16))
toolBarItemWindow = self.toolBar.AddTool( \
toolBarItem[0], toolBarItem[2], toolBarItemIcon)
self.toolBarItemsById[toolBarItem[0]] = toolBarItemWindow
if len(toolBarItem) == 7 \
and toolBarItem[1] == TID_COMMAND:
toolBarItemWindow.Enable(toolBarItem[6])
self.Bind(wx.EVT_TOOL, handler, toolBarItemWindow)
self.Bind(wx.EVT_TOOL_RCLICKED, handler, toolBarItemWindow)
# }}}
# {{{ onClose(self, event): XXX
def onClose(self, event):
self.Destroy(); self.__del__();
# }}}
# {{{ onFrameCommand(self, event): XXX
def onFrameCommand(self, event):
pass
# }}}
#
# __init__(self, *args, **kwargs): initialisation method
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
panelSkin = wx.Panel(self, wx.ID_ANY)
# Initialise menu bar, menus & menu items
self.menuItemsById = {}; menuBar = wx.MenuBar();
self._initMenus(menuBar, \
[self.MID_FILE, self.MID_EDIT, self.MID_TOOLS],
self.onFrameCommand)
self.SetMenuBar(menuBar)
# Initialise toolbar & toolbar items
self.toolBarItemsById = {}
self.toolBar = wx.ToolBar(panelSkin, -1, \
style=wx.HORIZONTAL|wx.TB_FLAT|wx.TB_NODIVIDER)
self.toolBar.SetToolBitmapSize((16,16))
self._initToolBars(self.toolBar, [self.BID_TOOLBAR], self.onFrameCommand)
self.toolBar.Realize(); self.toolBar.Fit();
# Initialise accelerators (hotkeys)
accelTable = wx.AcceleratorTable( \
self._initAccelTable(self.AID_EDIT, self.onFrameCommand))
self.SetAcceleratorTable(accelTable)
# Initialise status bar
self.statusBar = self.CreateStatusBar()
# Bind event handlers
self.Bind(wx.EVT_CLOSE, self.onClose)
# Set focus on & show window
self.SetFocus(); self.Show(True);
return panelSkin
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -22,13 +22,13 @@
# SOFTWARE.
#
import MiRCARTCanvasStore
from PIL import Image, ImageDraw, ImageFont
from MiRCARTFromTextFile import MiRCARTFromTextFile
import string, sys
class MiRCARTToPngFile:
"""XXX"""
inFile = inFilePath = inFromTextFile = None
inFile = inFromTextFile = None
outFontFilePath = outFontSize = None
# {{{ _ColourMapBold: mIRC colour number to RGBA map given ^B (bold)
@ -81,23 +81,23 @@ class MiRCARTToPngFile:
# }}}
# {{{ export(self, outFilePath): XXX
def export(self, outFilePath):
inSize = self.inFromTextFile.getSize();
outSize = [inSize[n] * self.outImgFontSize[n] for n in range(0, 2)]
inSize = (len(self.inCanvasMap[0]), len(self.inCanvasMap))
outSize = [a*b for a,b in zip(inSize, self.outImgFontSize)]
outCurPos = [0, 0]
outImg = Image.new("RGBA", outSize, (*self._ColourMapNormal[1], 255))
outImgDraw = ImageDraw.Draw(outImg)
for inCurRow in range(0, inSize[1]):
for inCurCol in range(0, len(self.inFromTextFile.outMap[inCurRow])):
inCurCell = self.inFromTextFile.outMap[inCurRow][inCurCol]
for inCurRow in range(len(self.inCanvasMap)):
for inCurCol in range(len(self.inCanvasMap[inCurRow])):
inCurCell = self.inCanvasMap[inCurRow][inCurCol]
outColours = [0, 0]
if inCurCell[1] & MiRCARTFromTextFile._CellState.CS_BOLD:
if inCurCell[1] & 0x02:
if inCurCell[2] != " ":
outColours[0] = self._ColourMapBold[inCurCell[0][0]]
outColours[1] = self._ColourMapBold[inCurCell[0][1]]
else:
if inCurCell[2] != " ":
outColours[0] = self._ColourMapNormal[inCurCell[0][0]]
outColours[1] = self._ColourMapNormal[inCurCell[0][1]]
outColours[1] = self._ColourMapNormal[inCurCell[0][1]]
outImgDraw.rectangle((*outCurPos, \
outCurPos[0] + self.outImgFontSize[0], \
outCurPos[1] + self.outImgFontSize[1]), \
@ -107,7 +107,7 @@ class MiRCARTToPngFile:
# XXX implement italic
outImgDraw.text(outCurPos, \
inCurCell[2], (*outColours[0], 255), self.outImgFont)
if inCurCell[1] & MiRCARTFromTextFile._CellState.CS_UNDERLINE:
if inCurCell[1] & 0x1f:
self._drawUnderLine(curPos, self.outImgFontSize, outImgDraw)
outCurPos[0] += self.outImgFontSize[0];
outCurPos[0] = 0
@ -116,11 +116,9 @@ class MiRCARTToPngFile:
# }}}
#
# __init__(self, inFilePath, fontFilePath="DejaVuSansMono.ttf", fontSize=11): initialisation method
def __init__(self, inFilePath, fontFilePath="DejaVuSansMono.ttf", fontSize=11):
self.inFilePath = inFilePath; self.inFile = open(inFilePath, "r");
self.inFromTextFile = MiRCARTFromTextFile(self.inFile)
# __init__(self, inCanvasMap, fontFilePath="DejaVuSansMono.ttf", fontSize=11): initialisation method
def __init__(self, inCanvasMap, fontFilePath="DejaVuSansMono.ttf", fontSize=11):
self.inCanvasMap = inCanvasMap
self.outFontFilePath = fontFilePath; self.outFontSize = int(fontSize);
self.outImgFont = ImageFont.truetype( \
self.outFontFilePath, self.outFontSize)
@ -130,7 +128,8 @@ class MiRCARTToPngFile:
#
# Entry point
def main(*argv):
MiRCARTToPngFile(argv[1], *argv[3:]).export(argv[2])
canvasStore = MiRCARTCanvasStore.MiRCARTCanvasStore(inFile=argv[1])
MiRCARTToPngFile(canvasStore.outMap, *argv[3:]).export(argv[2])
if __name__ == "__main__":
if ((len(sys.argv) - 1) < 2)\
or ((len(sys.argv) - 1) > 4):

View File

@ -26,8 +26,8 @@ class MiRCARTTool():
"""XXX"""
parentCanvas = None
# {{{ onMouseEvent(self, event, mapPoint, isDragging, isLeftDown, isRightDown): XXX
def onMouseEvent(self, event, mapPoint, isDragging, isLeftDown, isRightDown):
# {{{ onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown): XXX
def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown):
pass
# }}}

View File

@ -28,25 +28,19 @@ class MiRCARTToolRect(MiRCARTTool):
"""XXX"""
#
# onMouseEvent(self, event, mapPoint, isDragging, isLeftDown, isRightDown): XXX
def onMouseEvent(self, event, mapPoint, isDragging, isLeftDown, isRightDown):
# onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown): XXX
def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown):
brushColours = brushColours.copy()
if isLeftDown:
return [[False, [[0, 0, \
self.parentCanvas.mircFg, \
self.parentCanvas.mircFg, " "]]],
[True, [[0, 0, \
self.parentCanvas.mircFg, \
self.parentCanvas.mircFg, " "]]]]
brushColours[1] = brushColours[0]
return [[False, [[[0, 0], brushColours, 0, " "]]], \
[True, [[[0, 0], brushColours, 0, " "]]]]
elif isRightDown:
return [[False, [[0, 0, \
self.parentCanvas.mircBg, \
self.parentCanvas.mircBg, " "]]], \
[True, [[0, 0, \
self.parentCanvas.mircBg, \
self.parentCanvas.mircBg, " "]]]]
brushColours[0] = brushColours[1]
return [[False, [[[0, 0], brushColours, 0, " "]]], \
[True, [[[0, 0], brushColours, 0, " "]]]]
else:
return [[True, [[0, 0, \
self.parentCanvas.mircFg, \
self.parentCanvas.mircFg, " "]]]]
brushColours[1] = brushColours[0]
return [[True, [[[0, 0], brushColours, 0, " "]]]]
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,6 +1,6 @@
# MiRCART.py -- mIRC art editor for Windows & Linux (WIP)
* Prerequisites on Windows: install Python v3.6.x[1] and wxPython v4.x.x w/ the following elevated command prompt command line:
`pip install wxPython`
* Prerequisites on Windows: install Python v3.6.x[1] and script dependencies w/ the following elevated command prompt command line:
`pip install requests urllib3 wxPython`
* Prerequisites on Linux: python3 && python-wx{gtk2.8,tools} on Debian-family Linux distributions
* Screenshot:
![Screenshot](https://github.com/lalbornoz/MiRCARTools/raw/master/MiRCART.png "Screenshot")