help im trapped inside the commit message oh hey who are OH NO AHHHHHH STOP NO DONT DO THAT AHHHHHHHHHHHHHHHHHH IM BLEEDING

This commit is contained in:
Lucio Andrés Illanes Albornoz 2018-11-26 10:35:48 +01:00
parent 35f3323be1
commit bffd7711a1
75 changed files with 61 additions and 3687 deletions

2
ENNTool/.gitignore vendored
View File

@ -1,2 +0,0 @@
__pycache__/
*.sw[op]

View File

@ -1,191 +0,0 @@
#!/usr/bin/env python3
#
# ENNTool -- mIRC art animation tool (for EFnet #MiRCART) (WIP)
# Copyright (c) 2018 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
# This project is licensed under the terms of the MIT license.
#
# TODO:
# 1) -A, -S: replace w/ -s, implement animation script: render frame #1, render frame #2, ...; scrolling script; effects: rotate, smash into bricks, swirl, wave, ...
# 2) Feature: include ETA(s) @ progress bar(s)
# 3) Feature: autodetect video width from widest mircart
# 4) Feature: render mircart as 3D blocks vs flat surface
#
# 1) Optimisation: speed up ENNToolMiRCARTImporter
# 2) Cleanup: use names @ optdict + set from optdefaults
# 3) Feature: scrolling speed as <how many Y units>x<count of frame(s)>
# 4) Cleanup: use VAOs + glVertexAttribFormat + glVertexAttribBinding
# 5) Optimisation: split mIRC art into separate VBOs & implement rudimentary culling
# 6) Optimisation: only call glReadPixels() when changes were made relative to the last call
# 7) Split video output into separate module, switch to GUI
# 8) FBOs http://www.songho.ca/opengl/gl_fbo.html
#
from getopt import getopt, GetoptError
from glob import glob
from OpenGL.GL import *
import os, sys, time
import wx
from ENNToolGLCanvasPanel import ENNToolGLCanvas, ENNToolGLPanel
from ENNToolGLTTFTexture import ENNToolGLTTFTexture
from ENNToolGLVideoWriter import ENNToolGLVideoWriter
from ENNToolMiRCARTImporter import ENNToolMiRCARTImporter
class ENNToolApp(object):
"""XXX"""
# {{{ parseArgv(self, argv): XXX
def parseArgv(self, argv):
def usage(argv0):
print("usage: {}".format(os.path.basename(argv0)), file=sys.stderr)
print(" [-a] [-c x,y,z] [-f fps] [-h] [-o fname]".format(os.path.basename(argv0)), file=sys.stderr)
print(" [-p] [-r WxH] [-R WxH] [-s fname]", file=sys.stderr)
print(" [-S] [-t float] [-v] [--] fname..", file=sys.stderr)
print("", file=sys.stderr)
print(" -a........: select animation mode (UNIMPLEMENTED)", file=sys.stderr)
print(" -c x,y,z..: specify camera position", file=sys.stderr)
print(" -f fps....: set video FPS; defaults to 25", file=sys.stderr)
print(" -h........: show this screen", file=sys.stderr)
print(" -o fname..: output video filename; extension determines video type", file=sys.stderr)
print(" -p........: play video after rendering", file=sys.stderr)
print(" -r WxH....: set video resolution; defaults to 1152x864", file=sys.stderr)
print(" -R WxH....: set MiRCART cube resolution; defaults to 0.1x0.2", file=sys.stderr)
print(" -s fname..: input script filename", file=sys.stderr)
print(" -S........: select scrolling mode", file=sys.stderr)
print(" -t float..: scrolling rate in Y coordinates per frame", file=sys.stderr)
print(" -v........: be verbose", file=sys.stderr)
try:
optlist, argv = getopt(argv[1:], "Ac:f:ho:pr:R:s:St:v")
optdict = dict(optlist)
if "-h" in optdict:
usage(sys.argv[0]); exit(0);
elif not len(argv):
raise GetoptError("at least one MiRCART input fname must be specified")
if not "-f" in optdict:
optdict["-f"] = "25"
if not "-r" in optdict:
optdict["-r"] = "1152x864"
if not "-R" in optdict:
optdict["-R"] = "0.1x0.2"
if "-c" in optdict:
optdict["-c"] = [float(r) for r in optdict["-c"].split(",")][0:3]
if "-r" in optdict:
optdict["-r"] = [int(r) for r in optdict["-r"].split("x")][0:2]
if "-R" in optdict:
optdict["-R"] = [float(r) for r in optdict["-R"].split("x")][0:2]
except GetoptError as e:
print(e.msg); usage(sys.argv[0]); exit(1);
return argv, optdict
# }}}
# {{{ printProgress(self, progressCur, progressMax): XXX
def printProgress(self, progressCur, progressMax):
progressDiv = float(progressCur / progressMax)
if progressDiv >= 1:
progressDiv = 1; endChar = "\n";
else:
endChar = ""
print("\r[{:<50}] {}%".format(
("=" * int(progressDiv * 50)), int(progressDiv * 100)), end=endChar)
# }}}
# {{{ modeScroll(self, argv, optdict, GLVideoWriter, GLpanel, GLpanel, fps=25): XXX
def modeScroll(self, argv, optdict, GLVideoWriter, GLcanvas, GLpanel, fps=25):
MiRCART = []
if "-t" in optdict:
scrollRate = float(optdict["-t"])
else:
scrollRate = 0.1
if "-v" in optdict:
time0 = time.time()
for inFileArg in argv:
for inFile in sorted(glob(inFileArg)):
MiRCART += ENNToolMiRCARTImporter(inFile).outMap
if "-v" in optdict:
print("mIRC art import delta {:.3f}ms".format((time.time() - time0) * 1000))
if "-v" in optdict:
time0 = time.time()
artTextureId, artInfo = ENNToolGLTTFTexture(MiRCART, optdict["-R"], optdict["-r"]).getParams()
if "-v" in optdict:
print("TTF texture generation delta {:.3f}ms".format((time.time() - time0) * 1000))
artVbo, artVboLen, lastY, numVertices = GLcanvas.renderMiRCART(artInfo, MiRCART, cubeSize=optdict["-R"])
if "-v" in optdict:
print("{} vertices".format(numVertices))
def scrollFrameFun():
curY, rotateX, rotateY, translateY = 0, 0, 0, scrollRate
w, h = GLcanvas.GetClientSize(); w, h = max(w, 1.0), max(h, 1.0);
def scrollFrame():
nonlocal curY
self.printProgress(curY, lastY)
GLcanvas.renderFrame(artTextureId, artVbo, artVboLen)
if translateY:
glTranslatef(0, translateY, 0); curY += translateY
if rotateX:
glRotatef(rotateX * (180.0/w), 0.0, 1.0, 0.0)
if rotateY:
glRotatef(rotateY * (180.0/h), 1.0, 0.0, 0.0)
if "-o" in optdict:
GLVideoWriter.saveFrame()
else:
GLcanvas.SwapBuffers()
if curY >= lastY:
self.printProgress(curY, lastY)
if "-o" in optdict:
GLVideoWriter.saveVideo()
return False
return True
return scrollFrame
if "-o" in optdict:
frameFun = scrollFrameFun()
while True:
if not frameFun():
break
else:
GLpanel.frameFun = scrollFrameFun()
self.wxApp.MainLoop()
# }}}
# {{{ __init__(self, argv): XXX
def __init__(self, argv):
argv, optdict = self.parseArgv(argv)
self.wxApp = wx.App(False)
appFrameSize = [c + 128 for c in optdict["-r"]]
self.appFrame = wx.Frame(None, size=appFrameSize)
appPanelSkin = wx.Panel(self.appFrame, wx.ID_ANY)
videoFps, videoPath = int(optdict["-f"]), optdict["-o"] if "-o" in optdict else None
GLpanel = ENNToolGLPanel(appPanelSkin, size=optdict["-r"], parentFrame=self.appFrame)
GLcanvas = ENNToolGLCanvas(GLpanel, optdict["-r"])
if "-c" in optdict:
GLcanvas.initOpenGL(cameraPos=optdict["-c"])
else:
GLcanvas.initOpenGL()
GLcanvas.initShaders()
GLVideoWriter = ENNToolGLVideoWriter(videoPath, GLpanel.GetClientSize(), videoFps=videoFps)
if "-o" in optdict:
self.appFrame.Hide()
else:
self.appFrame.Show(); self.appFrame.SetFocus();
if "-v" in optdict:
time0 = time.time()
self.modeScroll(argv, optdict, GLVideoWriter, GLcanvas, GLpanel, fps=videoFps)
if "-v" in optdict:
print("delta {}s".format(time.time() - time0))
if "-o" in optdict \
and "-p" in optdict:
os.startfile(videoPath)
# }}}
#
# Entry point
def main(*argv):
ENNToolApp(argv)
if __name__ == "__main__":
main(*sys.argv)
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,204 +0,0 @@
#!/usr/bin/env python3
#
# ENNTool -- mIRC art animation tool (for EFnet #MiRCART) (WIP)
# Copyright (c) 2018 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
# This project is licensed under the terms of the MIT license.
#
# References:
# Wed, 27 Jun 2018 16:02:10 +0200 [1] <https://www.opengl.org/discussion_boards/showthread.php/125843-default-camera?p=954801&viewfull=1#post954801>
# Wed, 27 Jun 2018 16:02:11 +0200 [2] <https://www.opengl.org/discussion_boards/showthread.php/167808-2D-texture-problem-lines-between-textures>
# Wed, 27 Jun 2018 16:02:12 +0200 [3] <https://www.khronos.org/opengl/wiki/How_lighting_works#Good_Settings.>
# Wed, 27 Jun 2018 16:02:13 +0200 [4] <https://www.khronos.org/opengl/wiki/Common_Mistakes>
# Wed, 27 Jun 2018 16:02:14 +0200 [5] <https://www.khronos.org/opengl/wiki/Pixel_Transfer#Pixel_layout>
# Thu, 28 Jun 2018 18:32:50 +0200 [6] <https://stackoverflow.com/questions/18935203/shader-position-vec4-or-vec3>
# Tue, 03 Jul 2018 14:34:57 +0200 [7] <https://gamedev.stackexchange.com/questions/107793/binding-and-unbinding-what-would-you-do>
#
from ENNToolMiRCARTColours import ENNToolMiRCARTColoursFloat
from OpenGL.GL import *
from OpenGL.GL import shaders
import ctypes, wx, wx.glcanvas
class ENNToolGLCanvas(wx.glcanvas.GLCanvas):
# {{{ initOpenGL(self, cameraPos=(-5.0, 3.0, -5)): XXX
def initOpenGL(self, cameraPos=(-5.0, 3.0, -5)):
self.glContext = wx.glcanvas.GLContext(self)
self.SetCurrent(self.glContext)
# [1]
glViewport(0, 0, *self.curSize)
glMatrixMode(GL_PROJECTION)
glLoadIdentity(); glFrustum(-1, 1, -1, 1, 1, 100);
glMatrixMode(GL_MODELVIEW)
glEnable(GL_DEPTH_TEST)
glTranslatef(*cameraPos)
# }}}
# {{{ initShaders(self): XXX
def initShaders(self):
# Fragment shader
fs = shaders.compileShader("""
#version 330 core
in vec2 frgTexCoord;
in vec3 frgFgColour;
in vec3 frgBgColour;
uniform sampler2D texture;
layout(location = 0) out vec4 fragColour;
void main() {
vec4 texel = texture2D(texture, frgTexCoord);
if (texel.r == 0.0 && texel.g == 0.0 && texel.b == 0.0 && texel.a == 0.0) {
fragColour = vec4(frgBgColour.r, frgBgColour.g, frgBgColour.b, 1.0);
} else {
fragColour = vec4(frgFgColour.r, frgFgColour.g, frgFgColour.b, 1.0);
}
}
""", GL_FRAGMENT_SHADER)
# Vertex shader
vs = shaders.compileShader("""
#version 330 core
layout(location = 0) in vec4 vertex;
layout(location = 1) in vec2 texcoord;
layout(location = 2) in vec3 vexFgColour;
layout(location = 3) in vec3 vexBgColour;
out vec2 frgTexCoord;
out vec3 frgFgColour;
out vec3 frgBgColour;
uniform mat4 modelview;
uniform mat4 projection;
void main() {
gl_Position = projection * modelview * vertex;
frgTexCoord = texcoord;
frgFgColour = vexFgColour;
frgBgColour = vexBgColour;
}
""", GL_VERTEX_SHADER)
self.shader = shaders.compileProgram(vs, fs)
# }}}
# {{{ renderFrame(self, artTextureId, artVbo, artVboLen): XXX
def renderFrame(self, artTextureId, artVbo, artVboLen):
# Bind VBO and named texture & install shader program object
glBindBuffer(GL_ARRAY_BUFFER, artVbo)
glBindTexture(GL_TEXTURE_2D, artTextureId)
glUseProgram(self.shader)
# Specify modelview and projection matrix & texture unit uniforms for shader programs
modelview, projection = (GLfloat * 16)(), (GLfloat * 16)()
glGetFloatv(GL_MODELVIEW_MATRIX, modelview)
glGetFloatv(GL_PROJECTION_MATRIX, projection)
glUniformMatrix4fv(glGetUniformLocation(self.shader, "modelview"), 1, GL_FALSE, modelview)
glUniformMatrix4fv(glGetUniformLocation(self.shader, "projection"), 1, GL_FALSE, projection)
glUniform1i(glGetUniformLocation(self.shader, "texture"), 0)
# VBO vertices location
glEnableVertexAttribArray(0)
glVertexAttribPointer(0, 3, GL_FLOAT, False, 44, ctypes.c_void_p(0))
glVertexPointer(3, GL_FLOAT, 44, ctypes.c_void_p(0))
# VBO texture coordinates
glEnableVertexAttribArray(1)
glVertexAttribPointer(1, 2, GL_FLOAT, False, 44, ctypes.c_void_p(12))
glTexCoordPointer(2, GL_FLOAT, 44, ctypes.c_void_p(12))
# VBO foreground colours
glEnableVertexAttribArray(2)
glVertexAttribPointer(2, 3, GL_FLOAT, False, 44, ctypes.c_void_p(20))
glTexCoordPointer(3, GL_FLOAT, 44, ctypes.c_void_p(20))
# VBO background colours
glEnableVertexAttribArray(3)
glVertexAttribPointer(3, 3, GL_FLOAT, False, 44, ctypes.c_void_p(32))
glTexCoordPointer(3, GL_FLOAT, 44, ctypes.c_void_p(32))
# Clear colour and depth buffer, draw quads from VBO & clear state
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glDrawArrays(GL_QUADS, 0, artVboLen)
glDisableVertexAttribArray(0)
glBindTexture(GL_TEXTURE_2D, 0)
# }}}
# {{{ renderMiRCART(self, artInfo, artMap, centre=True, canvasCols=100, cubeSize=(0.1, 0.2)): XXX
def renderMiRCART(self, artInfo, artMap, centre=True, canvasCols=100, cubeSize=(0.1, 0.2)):
curPos, vertices, numVertices = [0, 0, 0], [], 0
for numRow in range(len(artMap)):
if centre and (len(artMap[numRow]) < canvasCols):
curPos[0] += (((canvasCols - len(artMap[numRow])) * cubeSize[0]) / 2)
for numCol in range(len(artMap[numRow])):
cubeFg = artMap[numRow][numCol][0]
cubeBg = artMap[numRow][numCol][1]
cubeAttrs = artMap[numRow][numCol][2]
cubeChar = artMap[numRow][numCol][3]
artCell = artInfo[cubeAttrs][cubeChar]
# Top Right, Top Left
vertices += curPos
vertices += artCell[0:2]
vertices += [*ENNToolMiRCARTColoursFloat[cubeFg]]
vertices += [*ENNToolMiRCARTColoursFloat[cubeBg]]
vertices += [curPos[0] - cubeSize[0], curPos[1], curPos[2]]
vertices += artCell[2:4]
vertices += ENNToolMiRCARTColoursFloat[cubeFg]
vertices += ENNToolMiRCARTColoursFloat[cubeBg]
# Bottom Left, Bottom Right
vertices += [curPos[0] - cubeSize[0], curPos[1] - cubeSize[1], curPos[2]]
vertices += artCell[4:6]
vertices += [*ENNToolMiRCARTColoursFloat[cubeFg]]
vertices += [*ENNToolMiRCARTColoursFloat[cubeBg]]
vertices += [curPos[0], curPos[1] - cubeSize[1], curPos[2]]
vertices += artCell[6:8]
vertices += ENNToolMiRCARTColoursFloat[cubeFg]
vertices += ENNToolMiRCARTColoursFloat[cubeBg]
curPos[0], numVertices = curPos[0] + cubeSize[0], numVertices + 4
curPos[0], curPos[1] = 0, curPos[1] - cubeSize[1]
artVbo = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, artVbo)
glBufferData(GL_ARRAY_BUFFER,
(ctypes.c_float*len(vertices))(*vertices),
GL_STATIC_DRAW)
return artVbo, len(vertices), -curPos[1], numVertices
# }}}
# {{{ __init__(self, parentCanvas, size): initialisation method
def __init__(self, parentCanvas, size):
super().__init__(parentCanvas, size=size)
self.curSize = list(size)
self.parentCanvas = parentCanvas
# }}}
class ENNToolGLPanel(wx.Panel):
"""XXX"""
# {{{ onPaint(self, event): XXX
def onPaint(self, event):
eventDc = wx.PaintDC(self)
eventUpdates = wx.RegionIterator(self.GetUpdateRegion())
paintFlag = True if eventUpdates.HaveRects() else False
if self.frameFun != None:
self.frameFun()
# }}}
# {{{ onTimer(self, event): XXX
def onTimer(self, event):
if self.frameFun != None:
if not self.frameFun():
event.GetTimer().Stop()
event.GetTimer().Destroy()
# }}}
# {{{ __init__(self, parent, size, defaultPos=(24,24), parentFrame=None): initialisation method
def __init__(self, parent, size, defaultPos=(24,24), parentFrame=None):
super().__init__(parent, pos=defaultPos, size=size)
self.curPos = list(defaultPos); self.curSize = list(size);
self.Bind(wx.EVT_PAINT, self.onPaint)
self.frameFun = None
self.timerTimer = wx.Timer(self, 1)
self.timerTimer.Start(40)
self.Bind(wx.EVT_TIMER, self.onTimer, self.timerTimer)
# }}}
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,149 +0,0 @@
#!/usr/bin/env python3
#
# ENNTool -- mIRC art animation tool (for EFnet #MiRCART) (WIP)
# Copyright (c) 2018 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
# This project is licensed under the terms of the MIT license.
#
# References:
# Thu, 28 Jun 2018 17:03:16 +0200 [1] <https://stackoverflow.com/questions/384759/how-to-convert-a-pil-image-into-a-numpy-array>
# Thu, 28 Jun 2018 17:04:59 +0200 [2] <https://www.khronos.org/opengl/wiki/Common_Mistakes#y-axis>
# Wed, 27 Jun 2018 16:02:12 +0200 [3] <https://www.khronos.org/opengl/wiki/How_lighting_works#Good_Settings.>
# Wed, 27 Jun 2018 16:02:13 +0200 [4] <https://www.khronos.org/opengl/wiki/Common_Mistakes>
# Wed, 27 Jun 2018 16:02:14 +0200 [5] <https://www.khronos.org/opengl/wiki/Pixel_Transfer#Pixel_layout>
# Wed, 04 Jul 2018 10:57:09 +0200 [6] <https://stackoverflow.com/questions/466204/rounding-up-to-next-power-of-2>
#
from collections import defaultdict
from OpenGL.GL import *
from PIL import Image, ImageDraw, ImageFont
import numpy
import os, string, sys
from ENNToolMiRCARTColours import ENNToolMiRCARTColours
from ENNToolMiRCARTImporter import ENNToolMiRCARTImporter
class ENNToolGLTTFTexture(object):
"""XXX"""
# {{{ _defaultDict(*args): XXX
@staticmethod
def _defaultDict(*args):
return defaultdict(*args)
# }}}
# {{{ _nestedDict(): XXX
@staticmethod
def _nestedDict():
return defaultdict(ENNToolGLTTFTexture._nestedDict)
# }}}
# {{{ _drawCharList(self, artInfo, charList, pilFontBold, pilFontNormal, pilImageDraw, pilImageSize): XXX
def _drawCharList(self, artInfo, charList, pilFontBold, pilFontNormal, pilImageDraw, pilImageSize):
curPos = [0, 0]
for newChar in charList:
if newChar[2] & ENNToolMiRCARTImporter._CellState.CS_BOLD:
pilFont, pilFontSize = pilFontBold, [pilFontBold.getsize(newChar[3])[0], pilFontBold.getsize(newChar[3])[1]]
else:
pilFont, pilFontSize = pilFontNormal, [pilFontNormal.getsize(newChar[3])[0], pilFontNormal.getsize(newChar[3])[1]]
if newChar[2] & ENNToolMiRCARTImporter._CellState.CS_UNDERLINE:
underLine = True
else:
underLine = False
if newChar[3] != " ":
pilImageDraw.text(curPos, newChar[3], (255, 255, 255, 255), pilFont)
if underLine and False:
pilImageDraw.line(
xy=(curPos[0], curPos[1] + (pilFontSize[1] - 2),
curPos[0] + pilFontSize[0], curPos[1] + pilFontSize[1]),
fill=(*ENNToolMiRCARTColours[newChar[0]], 255))
artInfo[newChar[2]][newChar[3]] = []
# Top Right
artInfo[newChar[2]][newChar[3]] += [float(curPos[0] + pilFontSize[0]) / pilImageSize[0], 0.0]
# Top Left
artInfo[newChar[2]][newChar[3]] += [float(curPos[0]) / pilImageSize[0], 0.0]
# Bottom Left
artInfo[newChar[2]][newChar[3]] += [float(curPos[0]) / pilImageSize[0], float(pilFontSize[1]) / pilImageSize[1]]
# Bottom Right
artInfo[newChar[2]][newChar[3]] += [float(curPos[0] + pilFontSize[0]) / pilImageSize[0], float(pilFontSize[1]) / pilImageSize[1]]
curPos[0] += pilFontSize[0]
return artInfo
# }}}
# {{{ _initArtInfoCharList(self): XXX
def _initArtInfoCharList(self, artMap):
artInfo, charList = ENNToolGLTTFTexture._nestedDict(), []
for numRow in range(len(artMap)):
for numCol in range(len(artMap[numRow])):
artFg = artMap[numRow][numCol][0]
artBg = artMap[numRow][numCol][1]
artAttrs = artMap[numRow][numCol][2]
artChar = artMap[numRow][numCol][3]
if artInfo[artAttrs][artChar] == {}:
artInfo[artAttrs][artChar] = None
charList += [[artFg, artBg, artAttrs, artChar]]
return artInfo, charList
# }}}
# {{{ _initFonts(self, charMap): XXX
def _initFonts(self, charMap):
fontBoldPathName = os.path.join("assets", "DejaVuSansMono-Bold.ttf")
fontNormalPathName = os.path.join("assets", "DejaVuSansMono.ttf")
fontSize = int("26")
pilFontBold = ImageFont.truetype(fontBoldPathName, fontSize)
pilFontMaxSize = [16, 32] # TODO
pilFontNormal = ImageFont.truetype(fontNormalPathName, fontSize)
return pilFontBold, pilFontMaxSize, pilFontNormal
# }}}
# {{{ _initImage(self, charList, pilFontMaxSize): XXX
def _initImage(self, charList, pilFontMaxSize):
pilImageSize = [pilFontMaxSize[0] * len(charList), pilFontMaxSize[1]]
for numDim in range(len(pilImageSize)):
if (pilImageSize[numDim] & (pilImageSize[numDim] - 1)) != 0:
pilImageSize[numDim] -= 1
pilImageSize[numDim] |= pilImageSize[numDim] >> 1
pilImageSize[numDim] |= pilImageSize[numDim] >> 2
pilImageSize[numDim] |= pilImageSize[numDim] >> 4
pilImageSize[numDim] |= pilImageSize[numDim] >> 8
pilImageSize[numDim] |= pilImageSize[numDim] >> 16
pilImageSize[numDim] += 1
pilImage = Image.new("RGBA", pilImageSize, (0, 0, 0, 0))
pilImageDraw = ImageDraw.Draw(pilImage)
return pilImage, pilImageDraw, pilImageSize
# }}}
# {{{ _initTexture(self, pilImage): XXX
def _initTexture(self, pilImage):
# [1], [2]
artTextureId = glGenTextures(1)
artTextureImage = pilImage
artTextureImageData = numpy.array(artTextureImage)
glBindTexture(GL_TEXTURE_2D, artTextureId)
glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
# [3]
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
# [4][5]
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
artTextureImage.size[0], artTextureImage.size[1],
0, GL_RGBA, GL_UNSIGNED_BYTE, artTextureImageData)
glBindTexture(GL_TEXTURE_2D, 0)
return artTextureId
# }}}
# {{{ getParams(self): XXX
def getParams(self):
return self.artTextureId, self.artInfo
# }}}
# {{{ __init__(self): initialisation method
def __init__(self, artMap, cubeSize, videoSize):
artInfo, charList = self._initArtInfoCharList(artMap)
pilFontBold, pilFontMaxSize, pilFontNormal = self._initFonts(charList)
pilImage, pilImageDraw, pilImageSize = self._initImage(charList, pilFontMaxSize)
artInfo = self._drawCharList(artInfo, charList, pilFontBold, pilFontNormal, pilImageDraw, pilImageSize)
artTextureId = self._initTexture(pilImage)
self.artTextureId = artTextureId
self.artInfo = artInfo
# }}}
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,68 +0,0 @@
#!/usr/bin/env python3
#
# ENNTool -- mIRC art animation tool (for EFnet #MiRCART) (WIP)
# Copyright (c) 2018 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
# This project is licensed under the terms of the MIT license.
#
# References:
# Tue, 03 Jul 2018 20:35:52 +0200 [1] <https://stackoverflow.com/questions/23930671/how-to-create-n-dim-numpy-array-from-a-pointer>
# Wed, 04 Jul 2018 10:02:22 +0200 [2] <http://www.songho.ca/opengl/gl_pbo.html>
#
from OpenGL.GL import *
import ctypes, cv2, numpy
class ENNToolGLVideoWriter(object):
"""XXX"""
# {{{ _copyFrames(self): XXX
def _copyFrames(self):
for numPbo in range(self.pboCount):
glBindBuffer(GL_PIXEL_PACK_BUFFER, self.pboList[numPbo])
frameBufferPtr = glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY)
frameBufferPtr = ctypes.cast(frameBufferPtr, ctypes.POINTER(ctypes.c_ubyte))
frameBuffer = numpy.ctypeslib.as_array(frameBufferPtr, shape=(self.videoSize[1], self.videoSize[0], 3))
frameBuffer = numpy.flipud(frameBuffer)
self.videoWriter.write(frameBuffer)
glUnmapBuffer(GL_PIXEL_PACK_BUFFER)
# }}}
# {{{ _initCv2(self, videoFps, videoPath, videoSize): XXX
def _initCv2(self, videoFps, videoPath, videoSize):
fourcc = cv2.VideoWriter_fourcc(*"avc1")
videoWriter = cv2.VideoWriter(videoPath, fourcc, videoFps, tuple(videoSize), True)
return videoWriter
# }}}
# {{{ _initPbos(self, pboCount, videoSize): XXX
def _initPbos(self, pboCount, videoSize):
pboBufs, pboCur, pboList = [None] * pboCount, 0, [None] * pboCount
for numPbo in range(pboCount):
pboList[numPbo] = glGenBuffers(1)
glBindBuffer(GL_PIXEL_PACK_BUFFER, pboList[numPbo])
glBufferData(GL_PIXEL_PACK_BUFFER,
videoSize[0] * videoSize[1] * 3, None, GL_STREAM_READ)
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)
return pboBufs, pboCount, pboCur, pboList
# }}}
# {{{ saveFrame(self): XXX
def saveFrame(self):
glBindBuffer(GL_PIXEL_PACK_BUFFER, self.pboList[self.pboCur])
glReadPixels(0, 0, self.videoSize[0], self.videoSize[1], GL_BGR, GL_UNSIGNED_BYTE, ctypes.c_void_p(0))
self.pboCur += 1
if self.pboCur >= self.pboCount:
self._copyFrames(); self.pboCur = 0;
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0)
# }}}
# {{{ saveVideo(self): XXX
def saveVideo(self):
return
# }}}
# {{{ __init__(self, videoPath, videoSize, videoFps=25): XXX
def __init__(self, videoPath, videoSize, videoFps=25):
videoWriter = self._initCv2(videoFps, videoPath, videoSize)
self.pboBufs, self.pboCount, \
self.pboCur, self.pboList = self._initPbos(videoFps, videoSize)
self.videoFps, self.videoPath, \
self.videoSize, self.videoWriter = videoFps, videoPath, videoSize, videoWriter
# }}}
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,52 +0,0 @@
#!/usr/bin/env python3
#
# ENNTool -- mIRC art animation tool (for EFnet #MiRCART) (WIP)
# Copyright (c) 2018 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
# This project is licensed under the terms of the MIT license.
#
#
# MiRCARTColours: mIRC colour number to RGBA map given none of ^[BFV_] (bold, italic, reverse, underline],
#
ENNToolMiRCARTColours = [
[255, 255, 255], # White
[0, 0, 0], # Black
[0, 0, 187], # Blue
[0, 187, 0], # Green
[255, 85, 85], # Light Red
[187, 0, 0], # Red
[187, 0, 187], # Purple
[187, 187, 0], # Yellow
[255, 255, 85], # Light Yellow
[85, 255, 85], # Light Green
[0, 187, 187], # Cyan
[85, 255, 255], # Light Cyan
[85, 85, 255], # Light Blue
[255, 85, 255], # Pink
[85, 85, 85], # Grey
[187, 187, 187], # Light Grey
]
#
# MiRCARTColours: mIRC colour number to RGBA float map given none of ^[BFV_] (bold, italic, reverse, underline],
#
ENNToolMiRCARTColoursFloat = [
[1.00, 1.00, 1.00], # White
[0.00, 0.00, 0.00], # Black
[0.00, 0.00, 0.73], # Blue
[0.00, 0.73, 0.00], # Green
[1.00, 0.33, 0.33], # Light Red
[0.73, 0.00, 0.00], # Red
[0.73, 0.00, 0.73], # Purple
[0.73, 0.73, 0.00], # Yellow
[1.00, 1.00, 0.33], # Light Yellow
[0.33, 1.00, 0.33], # Light Green
[0.00, 0.73, 0.73], # Cyan
[0.33, 1.00, 1.00], # Light Cyan
[0.33, 0.33, 1.00], # Light Blue
[1.00, 0.33, 1.00], # Pink
[0.33, 0.33, 0.33], # Grey
[0.73, 0.73, 0.73], # Light Grey
]
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,134 +0,0 @@
#!/usr/bin/env python3
#
# ENNTool -- mIRC art animation tool (for EFnet #MiRCART) (WIP)
# Copyright (c) 2018 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
# This project is licensed under the terms of the MIT license.
#
# TODO:
# 1) un-Quick'n'Dirty-ify
#
import chardet
class ENNToolMiRCARTImporter(object):
"""XXX"""
# {{{ _CellState(): Cell state
class _CellState():
CS_NONE = 0x00
CS_BOLD = 0x01
CS_ITALIC = 0x02
CS_UNDERLINE = 0x04
# }}}
# {{{ _ParseState(): Parsing loop state
class _ParseState():
PS_CHAR = 1
PS_COLOUR_DIGIT0 = 2
PS_COLOUR_DIGIT1 = 3
# }}}
# {{{ _flipCellStateBit(self, cellState, bit): XXX
def _flipCellStateBit(self, cellState, bit):
if cellState & bit:
return cellState & ~bit
else:
return cellState | bit
# }}}
# {{{ _parseCharAsColourSpec(self, colourSpec, curColours): XXX
def _parseCharAsColourSpec(self, colourSpec, curColours):
if len(colourSpec) > 0:
colourSpec = colourSpec.split(",")
if len(colourSpec) == 2 \
and len(colourSpec[1]) > 0:
return [int(colourSpec[0] or curColours[0]), \
int(colourSpec[1])]
elif len(colourSpec) == 1 \
or len(colourSpec[1]) == 0:
return [int(colourSpec[0]), curColours[1]]
else:
return [15, 1]
# }}}
# {{{ fromTextFile(self, pathName): XXX
def fromTextFile(self, pathName):
with open(pathName, "rb") as fileObject:
inFileEncoding = chardet.detect(fileObject.read())["encoding"]
self.inFile = open(pathName, "r", encoding=inFileEncoding)
self.inSize = self.outMap = None;
inCurColourSpec = ""; inCurRow = -1;
inLine = self.inFile.readline()
inSize = [0, 0]; outMap = []; inMaxCols = 0;
while inLine:
inCellState = self._CellState.CS_NONE
inParseState = self._ParseState.PS_CHAR
inCurCol = 0; inMaxCol = len(inLine);
inCurColourDigits = 0; inCurColours = [15, 1]; inCurColourSpec = "";
inCurRow += 1; outMap.append([]); inRowCols = 0; inSize[1] += 1;
while inCurCol < inMaxCol:
inChar = inLine[inCurCol]
if inChar in set("\r\n"): \
inCurCol += 1
elif inParseState == self._ParseState.PS_CHAR:
inCurCol += 1
if inChar == "":
inCellState = self._flipCellStateBit( \
inCellState, self._CellState.CS_BOLD)
elif inChar == "":
inParseState = self._ParseState.PS_COLOUR_DIGIT0
elif inChar == "":
inCellState = self._flipCellStateBit( \
inCellState, self._CellState.CS_ITALIC)
elif inChar == "":
inCellState |= self._CellState.CS_NONE
inCurColours = [15, 1]
elif inChar == "":
inCurColours = [inCurColours[1], inCurColours[0]]
elif inChar == "":
inCellState = self._flipCellStateBit( \
inCellState, self._CellState.CS_UNDERLINE)
else:
inRowCols += 1
outMap[inCurRow].append([*inCurColours, inCellState, inChar])
elif inParseState == self._ParseState.PS_COLOUR_DIGIT0 \
or inParseState == self._ParseState.PS_COLOUR_DIGIT1:
if inChar == "," \
and inParseState == self._ParseState.PS_COLOUR_DIGIT0:
if (inCurCol + 1) < inMaxCol \
and not inLine[inCurCol + 1] in set("0123456789"):
inCurColours = self._parseCharAsColourSpec( \
inCurColourSpec, inCurColours)
inCurColourDigits = 0; inCurColourSpec = "";
inParseState = self._ParseState.PS_CHAR
else:
inCurCol += 1
inCurColourDigits = 0; inCurColourSpec += inChar;
inParseState = self._ParseState.PS_COLOUR_DIGIT1
elif inChar in set("0123456789") \
and inCurColourDigits == 0:
inCurCol += 1
inCurColourDigits += 1; inCurColourSpec += inChar;
elif inChar in set("0123456789") \
and inCurColourDigits == 1 \
and inCurColourSpec[-1] == "0":
inCurCol += 1
inCurColourDigits += 1; inCurColourSpec += inChar;
elif inChar in set("012345") \
and inCurColourDigits == 1 \
and inCurColourSpec[-1] == "1":
inCurCol += 1
inCurColourDigits += 1; inCurColourSpec += inChar;
else:
inCurColours = self._parseCharAsColourSpec( \
inCurColourSpec, inCurColours)
inCurColourDigits = 0; inCurColourSpec = "";
inParseState = self._ParseState.PS_CHAR
inMaxCols = max(inMaxCols, inRowCols)
inLine = self.inFile.readline()
inSize[0] = inMaxCols; self.inSize = inSize; self.outMap = outMap;
self.inFile.close()
# }}}
# {{{ __init__(self, inFile): initialisation method
def __init__(self, inFile):
self.inFile = inFile; self.inSize = self.outMap = None;
self.fromTextFile(inFile)
# }}}
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,35 +0,0 @@
# ENNTool -- mIRC art animation tool (for EFnet #MiRCART) (WIP)
Copyright (c) 2018 Lucio Andrés Illanes Albornoz <<lucio@lucioillanes.de>>
This project is licensed under the terms of the MIT licence.
## Installation instructions on Windows
1. Install Python v>=3.5.x[[4](#r4)]
2. Install script dependencies w/ the following elevated command prompt command line:
`pip install chardet numpy Pillow PyOpenGL wxPython`
3. Download OpenCV wheel[[1](#r1)] and install w/ the following elevated command prompt command line:
`pip install <path to OpenCV wheel>`
## How to run
```
usage: ENNTool.py
[-A] [-f fps] [-h] [-o fname]
[-p] [-r WxH] [-R WxH] [-s fname]
[-S] [-v] [--] fname..
-a........: select animation mode (UNIMPLEMENTED)
-f fps....: set video FPS; defaults to 25
-h........: show this screen
-o fname..: output video filename; extension determines video type
-p........: play video after rendering
-r WxH....: set video resolution; defaults to 1152x864
-R WxH....: set MiRCART cube resolution; defaults to 0.1x0.2
-s fname..: input script filename
-S........: select scrolling mode
-v........: be verbose
```
## References
``Wed, 04 Jul 2018 09:33:53 +0200 [1]`` <a href="https://www.lfd.uci.edu/~gohlke/pythonlibs/#opencv" id="r1">Python Extension Packages for Windows - Christoph Gohlke</a>
``Wed, 04 Jul 2018 09:38:28 +0200 [2]`` <a href="https://github.com/cisco/openh264/releases" id="r2">Releases · cisco/openh264 · GitHub</a>
``Wed, 04 Jul 2018 09:49:38 +0200 [3]`` <a href="https://github.com/opencv/opencv/issues/6080" id="r3">opencv_ffmpeg and OpenH264-x.y.z · Issue #6080 · opencv/opencv · GitHub</a>
``Wed, 04 Jul 2018 10:24:12 +0200 [4]`` <a href="https://www.python.org/downloads/windows" id="r4">Python Releases for Windows | Python.org</a>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

View File

@ -1,36 +0,0 @@
0,1 3,3 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 3,3 0,1 0,0 1,1 0,1 0,0 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 1,1 9,9 1,1 9,9 1,1 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1
3,3 0,1 3,3 0,1 9,9 0,1 9,9 1,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 0,0 0,1 0,0 0,1 0,0 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 1,1 9,9 0,1 9,9 1,1 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1
0,1 3,3 0,1 9,9 0,1 11,11 10,10 11,11 0,1 9,9 0,1 9,9 0,1 3,3 0,1 3,3 0,1 0,0 0,1 0,0 0,1 0,0 0,1 9,9 0,1 9,9 0,1 9,9 0,1 1,1 9,9 0,1 1,1 0,1 9,9 0,1 9,9 0,1
0,1 3,3 0,1 3,3 0,1 10,10 11,11 10,10 11,11 10,10 0,1 3,3 0,1 3,3 0,1 0,0 0,1 3,3 0,1 3,3 0,1 1,1 3,3 1,1 3,3 1,1 9,9 1,1 9,9 1,1 3,3 1,1 3,3 1,1 0,1 3,3 0,1 3,3 0,1
9,9 1,1 3,3 1,1 10,10 11,11 10,10 11,11 10,10 1,1 0,0 1,1 11,11 1,10 1,1 11,11 1,1 3,3 1,1 9,9 1,1 3,3 1,1 11,11 1,1 1,10 11,11 0,1 9,9
9,9 1,1 10,10 11,11 10,10 11,11 10,10 11,11 1,1 3,3 1,1 11,11 1,10 1,1 11,11 1,1 3,3 1,1 3,3 1,1 11,11 1,1 1,10 11,11 0,1 9,9
9,9 1,1 10,10 11,11 10,10 11,11 10,10 1,1 8,8 1,1 11,11 1,10 1,1 11,11 1,1 3,3 1,1 11,11 1,1 1,10 11,11 1,1 0,1 9,9
9,9 1,1 11,11 10,10 11,11 10,10 11,11 10,10 11,11 10,10 1,1 8,8 1,1 8,8 1,1 11,11 1,10 1,1 11,11 1,1 1,10 11,11 1,1 0,1 9,9
9,9 1,1 11,11 10,10 11,11 10,10 11,10 10,10 11,11 10,10 1,1 8,8 1,1 8,8 1,1 11,11 1,10 1,1 1,10 11,11 1,1 0,1 9,9
9,9 1,1 11,11 10,10 11,11 10,10 11,11 10,10 1,1 8,8 1,1 8,8 1,1 8,8 1,1 0,0 1,1 8,8 1,1 8,8 1,1 8,8 1,1 11,11 1,10 11,11 1,10 11,11 1,1 0,1 9,9
1,3 9,9 1,1 11,11 10,10 11,11 10,10 11,11 1,1 8,8 1,1 8,8 1,1 8,8 1,1 0,0 1,1 0,0 1,1 8,8 1,1 8,8 1,1 8,8 1,1 11,11 10,10 11,11 1,1 0,1 9,9 1,3
3,3 9,9 1,1 3,3 1,1 3,3 1,1 11,11 10,10 1,1 8,8 1,1 8,8 1,1 8,8 1,1 0,0 1,1 8,8 1,1 8,8 1,1 8,8 1,1 3,3 9,9 3,3 1,1 0,1 9,9 1,3
3,3 9,9 1,1 3,3 1,1 3,3 1,1 3,3 1,1 3,3 1,1 8,8 1,1 8,8 1,1 8,8 1,1 0,0 1,1 8,8 1,1 8,8 1,1 0,0 1,1 8,8 1,1 8,8 1,1 8,8 1,1 3,3 9,9 1,1 0,1 9,9 1,3
3,3 9,9 1,1 3,3 1,1 3,3 1,1 3,3 1,1 3,3 1,1 8,8 1,1 8,8 1,1 8,8 1,1 0,0 1,1 0,0 1,1 8,8 1,1 8,8 1,1 0,0 1,1 0,0 1,1 8,8 1,1 8,8 1,1 8,8 1,1 3,3 9,9 3,3 1,1 0,1 9,9 1,3
3,3 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 7,7 8,8 1,1 8,8 1,1 8,8 1,1 0,0 1,1 8,8 1,1 0,0 1,1 8,8 1,1 8,8 1,1 8,8 1,1 9,9 3,3 1,1 0,1 9,9 1,3
1,3 3,3 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 7,7 8,8 1,1 8,8 1,1 8,8 1,1 3,3 9,9 3,3 1,1 0,1 9,9 1,3
11,11 3,3 9,9 1,1 7,7 8,8 1,1 8,8 1,1 8,8 1,1 8,8 1,1 3,3 9,9 1,1 0,1 9,9 1,3 11,11
11,11 3,3 9,9 1,1 3,3 1,1 3,3 1,1 3,3 1,1 3,3 1,1 3,3 1,1 3,3 1,1 7,7 8,8 1,1 0,0 1,1 8,8 1,1 3,3 9,9 3,3 1,1 0,1 9,9 1,3 11,11
11,11 1,3 3,3 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 7,7 8,8 1,1 8,8 1,1 9,9 3,3 1,1 0,1 9,9 1,3 11,11
10,10 3,11 1,3 3,3 9,9 1,1 3,3 1,1 3,3 1,1 7,7 8,8 1,1 0,0 1,1 0,0 1,1 0,0 1,1 8,8 1,1 3,3 1,1 9,9 1,3 3,11 10,10
10,10 3,11 1,3 3,3 9,9 1,1 3,3 1,1 3,3 1,1 3,3 1,1 3,3 1,1 3,3 1,1 7,7 8,8 8,1 1,1 8,1 8,8 1,1 9,9 3,3 1,1 9,9 1,3 3,11 10,10
10,10 3,11 1,3 3,3 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 7,7 8,8 8,1 0,0 1,1 0,0 1,1 0,0 8,1 8,8 1,1 3,3 9,9 1,3 3,11 10,10
10,10 3,11 3,3 9,9 7,7 8,8 8,1 1,1 8,1 8,8 7,7 9,9 3,3 1,3 3,11 10,10
10,10 11,11 3,3 7,7 8,8 8,1 0,0 8,1 8,8 7,7 3,3 11,11 10,10
10,10 11,11 3,3 9,9 7,7 8,8 8,1 8,8 7,7 9,9 3,3 11,11 10,10
10,10 11,11 3,3 9,9 3,3 7,7 3,3 9,9 3,3 11,11 10,10
10,10 11,11 3,3 9,9 3,3 11,11 3,3 9,9 3,3 11,11 10,10
11,11 3,3 9,9 3,3 11,11 10,10 11,11 3,3 9,9 3,3 11,11
11,11 3,3 9,9 3,3 11,11 10,10 11,11 10,10 11,11 3,3 9,9 3,3 11,11
11,11 3,3 9,9 3,3 11,11 10,10 11,11 10,10 11,11 10,10 11,11 3,3 9,9 3,3 11,11
11,11 3,3 9,9 3,3 11,11 10,10 11,11 10,10 11,11 3,3 9,9 3,3 11,11
10,10 11,11 3,3 9,9 3,3 11,11 10,10 11,11 3,3 9,9 3,3 11,11 10,10
10,10 11,11 3,3 9,9 3,3 11,11 3,3 9,9 3,3 11,11 10,10
10,10 11,11 3,3 9,9 3,3 9,9 3,3 11,11 10,10
10,10 11,11 3,3 9,9 3,3 11,11 10,10
10,10 11,11 3,3 11,11 10,10

Binary file not shown.

Binary file not shown.

View File

@ -1,59 +0,0 @@
-------------------------------------------------------
About The Cisco-Provided Binary of OpenH264 Video Codec
-------------------------------------------------------
Cisco provides this program under the terms of the BSD license.
Additionally, this binary is licensed under Ciscos AVC/H.264 Patent Portfolio License from MPEG LA, at no cost to you, provided that the requirements and conditions shown below in the AVC/H.264 Patent Portfolio sections are met.
As with all AVC/H.264 codecs, you may also obtain your own patent license from MPEG LA or from the individual patent owners, or proceed at your own risk. Your rights from Cisco under the BSD license are not affected by this choice.
For more information on the OpenH264 binary licensing, please see the OpenH264 FAQ found at http://www.openh264.org/faq.html#binary
A corresponding source code to this binary program is available under the same BSD terms, which can be found at http://www.openh264.org
-----------
BSD License
-----------
Copyright © 2014 Cisco Systems, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-----------------------------------------
AVC/H.264 Patent Portfolio License Notice
-----------------------------------------
The binary form of this Software is distributed by Cisco under the AVC/H.264 Patent Portfolio License from MPEG LA, and is subject to the following requirements, which may or may not be applicable to your use of this software:
THIS PRODUCT IS LICENSED UNDER THE AVC PATENT PORTFOLIO LICENSE FOR THE PERSONAL USE OF A CONSUMER OR OTHER USES IN WHICH IT DOES NOT RECEIVE REMUNERATION TO (i) ENCODE VIDEO IN COMPLIANCE WITH THE AVC STANDARD (“AVC VIDEO”) AND/OR (ii) DECODE AVC VIDEO THAT WAS ENCODED BY A CONSUMER ENGAGED IN A PERSONAL ACTIVITY AND/OR WAS OBTAINED FROM A VIDEO PROVIDER LICENSED TO PROVIDE AVC VIDEO. NO LICENSE IS GRANTED OR SHALL BE IMPLIED FOR ANY OTHER USE. ADDITIONAL INFORMATION MAY BE OBTAINED FROM MPEG LA, L.L.C. SEE HTTP://WWW.MPEGLA.COM
Accordingly, please be advised that content providers and broadcasters using AVC/H.264 in their service may be required to obtain a separate use license from MPEG LA, referred to as "(b) sublicenses" in the SUMMARY OF AVC/H.264 LICENSE TERMS from MPEG LA found at http://www.openh264.org/mpegla
---------------------------------------------
AVC/H.264 Patent Portfolio License Conditions
---------------------------------------------
In addition, the Cisco-provided binary of this Software is licensed under Cisco's license from MPEG LA only if the following conditions are met:
1. The Cisco-provided binary is separately downloaded to an end users device, and not integrated into or combined with third party software prior to being downloaded to the end users device;
2. The end user must have the ability to control (e.g., to enable, disable, or re-enable) the use of the Cisco-provided binary;
3. Third party software, in the location where end users can control the use of the Cisco-provided binary, must display the following text:
"OpenH264 Video Codec provided by Cisco Systems, Inc."
4. Any third-party software that makes use of the Cisco-provided binary must reproduce all of the above text, as well as this last condition, in the EULA and/or in another location where licensing information is to be presented to the end user.
v1.0

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

View File

@ -1,43 +0,0 @@
#!/usr/bin/env python3
#
# MiRCART.py -- mIRC art editor for Windows & Linux
# 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.
#
from MiRCARTFrame import MiRCARTFrame
import sys, wx
#
# Entry point
def main(*argv):
wxApp = wx.App(False)
appFrame = MiRCARTFrame(None)
if len(argv) > 1 \
and len(argv[1]) > 0:
appFrame.panelCanvas.canvasInterface.canvasPathName = argv[1]
appFrame.panelCanvas.canvasImportStore.importTextFile(argv[1])
appFrame.panelCanvas.canvasImportStore.importIntoPanel()
appFrame.onCanvasUpdate(pathName=argv[1], undoLevel=-1)
wxApp.MainLoop()
if __name__ == "__main__":
main(*sys.argv)
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,221 +0,0 @@
#!/usr/bin/env python3
#
# MiRCARTCanvas.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.
#
from MiRCARTCanvasBackend import MiRCARTCanvasBackend
from MiRCARTCanvasJournal import MiRCARTCanvasJournal
from MiRCARTCanvasExportStore import MiRCARTCanvasExportStore, haveMiRCARTToPngFile, haveUrllib
from MiRCARTCanvasImportStore import MiRCARTCanvasImportStore
from MiRCARTCanvasInterface import MiRCARTCanvasInterface
from MiRCARTImgurApiKey import MiRCARTImgurApiKey
import wx
class MiRCARTCanvas(wx.Panel):
"""XXX"""
parentFrame = None
defaultCanvasPos = defaultCanvasSize = defaultCellSize = None
canvasMap = canvasPos = canvasSize = None
brushColours = brushPos = brushSize = None
canvasBackend = canvasJournal = None
canvasExportStore = canvasImportStore = None
canvasInterface = None
imgurApiKey = MiRCARTImgurApiKey.imgurApiKey
# {{{ _commitPatch(self, patch): XXX
def _commitPatch(self, patch):
self.canvasMap[patch[1]][patch[0]] = patch[2:]
# }}}
# {{{ _dispatchDeltaPatches(self, deltaPatches): XXX
def _dispatchDeltaPatches(self, deltaPatches):
eventDc = self.canvasBackend.getDeviceContext(self)
for patch in deltaPatches:
if self.canvasBackend.drawPatch(eventDc, patch):
self._commitPatch(patch)
self.parentFrame.onCanvasUpdate(undoLevel=self.canvasJournal.patchesUndoLevel)
# }}}
# {{{ _dispatchPatch(self, eventDc, isCursor, patch): XXX
def _dispatchPatch(self, eventDc, isCursor, patch):
if not self._canvasDirtyCursor:
self.canvasBackend.drawCursorMaskWithJournal( \
self.canvasJournal, eventDc)
self._canvasDirtyCursor = True
if self.canvasBackend.drawPatch(eventDc, patch):
patchDeltaCell = self.canvasMap[patch[1]][patch[0]]
patchDelta = [*patch[0:2], *patchDeltaCell]
if isCursor:
self.canvasJournal.pushCursor(patchDelta)
else:
if not self._canvasDirty:
self.canvasJournal.pushDeltas([], [])
self._canvasDirty = True
self.canvasJournal.updateCurrentDeltas(patchDelta, patch)
self._commitPatch(patch)
# }}}
# {{{ onPanelClose(self, event): XXX
def onPanelClose(self, event):
self.Destroy()
# }}}
# {{{ onPanelEnterWindow(self, event): XXX
def onPanelEnterWindow(self, event):
self.parentFrame.SetFocus()
# }}}
# {{{ onPanelInput(self, event): XXX
def onPanelInput(self, event):
eventDc = self.canvasBackend.getDeviceContext(self)
eventType = event.GetEventType()
self._canvasDirty = self._canvasDirtyCursor = False
tool = self.canvasInterface.canvasTool
if eventType == wx.wxEVT_CHAR:
mapPoint = self.brushPos
doSkip = tool.onKeyboardEvent( \
event, mapPoint, self.brushColours, self.brushSize, \
chr(event.GetUnicodeKey()), self._dispatchPatch, eventDc)
if doSkip:
event.Skip(); return;
else:
mapPoint = self.canvasBackend.xlateEventPoint(event, eventDc)
if mapPoint[0] >= self.canvasSize[0] \
or mapPoint[1] >= self.canvasSize[1]:
return
self.brushPos = mapPoint
tool.onMouseEvent( \
event, mapPoint, self.brushColours, self.brushSize, \
event.Dragging(), event.LeftIsDown(), event.RightIsDown(), \
self._dispatchPatch, eventDc)
if self._canvasDirty:
self.parentFrame.onCanvasUpdate(cellPos=self.brushPos, \
undoLevel=self.canvasJournal.patchesUndoLevel)
if eventType == wx.wxEVT_MOTION:
self.parentFrame.onCanvasUpdate(cellPos=mapPoint)
# }}}
# {{{ onPanelLeaveWindow(self, event): XXX
def onPanelLeaveWindow(self, event):
eventDc = self.canvasBackend.getDeviceContext(self)
self.canvasBackend.drawCursorMaskWithJournal( \
self.canvasJournal, eventDc)
# }}}
# {{{ onPanelPaint(self, event): XXX
def onPanelPaint(self, event):
self.canvasBackend.onPanelPaintEvent(self, event)
# }}}
# {{{ onStoreUpdate(self, newCanvasSize, newCanvas=None): XXX
def onStoreUpdate(self, newCanvasSize, newCanvas=None):
self.resize(newCanvasSize=newCanvasSize)
eventDc = self.canvasBackend.getDeviceContext(self)
for numRow in range(self.canvasSize[1]):
for numCol in range(self.canvasSize[0]):
if newCanvas != None \
and numRow < len(newCanvas) \
and numCol < len(newCanvas[numRow]):
self._commitPatch([ \
numCol, numRow, *newCanvas[numRow][numCol]])
self.canvasBackend.drawPatch(eventDc, \
[numCol, numRow, \
*self.canvasMap[numRow][numCol]])
wx.SafeYield()
# }}}
# {{{ resize(self, newCanvasSize): XXX
def resize(self, newCanvasSize):
if newCanvasSize != self.canvasSize:
if self.canvasMap == None:
self.canvasMap = []; oldCanvasSize = [0, 0];
else:
oldCanvasSize = self.canvasSize
deltaCanvasSize = [b-a for a,b in zip(oldCanvasSize, newCanvasSize)]
newWinSize = [a*b for a,b in zip(newCanvasSize, self.canvasBackend.cellSize)]
self.SetMinSize(newWinSize)
self.SetSize(wx.DefaultCoord, wx.DefaultCoord, *newWinSize)
curWindow = self
while curWindow != None:
curWindow.Layout()
curWindow = curWindow.GetParent()
self.canvasBackend.resize(newCanvasSize, self.canvasBackend.cellSize)
eventDc = self.canvasBackend.getDeviceContext(self)
self.canvasJournal.resetCursor(); self.canvasJournal.resetUndo();
if deltaCanvasSize[0] < 0:
for numRow in range(oldCanvasSize[1]):
del self.canvasMap[numRow][-1:(deltaCanvasSize[0]-1):-1]
else:
for numRow in range(oldCanvasSize[1]):
self.canvasMap[numRow].extend( \
[[1, 1, 0, " "]] * deltaCanvasSize[0])
for numNewCol in range(oldCanvasSize[0], newCanvasSize[0]):
self.canvasBackend.drawPatch( \
eventDc, [numNewCol, numRow, \
*self.canvasMap[numRow][-1]])
if deltaCanvasSize[1] < 0:
del self.canvasMap[-1:(deltaCanvasSize[1]-1):-1]
else:
for numNewRow in range(oldCanvasSize[1], newCanvasSize[1]):
self.canvasMap.extend( \
[[[1, 1, 0, " "]] * newCanvasSize[0]])
for numNewCol in range(newCanvasSize[0]):
self.canvasBackend.drawPatch( \
eventDc, [numNewCol, numNewRow, \
*self.canvasMap[-1][-1]])
self.canvasSize = newCanvasSize
wx.SafeYield()
self.parentFrame.onCanvasUpdate(size=newCanvasSize, undoLevel=-1)
# }}}
# {{{ __del__(self): destructor method
def __del__(self):
if self.canvasMap != None:
self.canvasMap.clear(); self.canvasMap = None;
# }}}
#
# __init__(self, parent, parentFrame, defaultCanvasPos, defaultCanvasSize, defaultCellSize): initialisation method
def __init__(self, parent, parentFrame, defaultCanvasPos, defaultCanvasSize, defaultCellSize):
super().__init__(parent, pos=defaultCanvasPos, \
size=[w*h for w,h in zip(defaultCanvasSize, defaultCellSize)])
self.parentFrame = parentFrame
self.canvasMap = None
self.canvasPos = defaultCanvasPos; self.canvasSize = defaultCanvasSize;
self.defaultCanvasPos = defaultCanvasPos; self.defaultCanvasSize = defaultCanvasSize;
self.brushColours = [4, 1]; self.brushPos = [0, 0]; self.brushSize = [1, 1];
self.parentFrame.onCanvasUpdate( \
brushSize=self.brushSize, colours=self.brushColours)
self.canvasBackend = MiRCARTCanvasBackend(defaultCanvasSize, defaultCellSize)
self.canvasJournal = MiRCARTCanvasJournal()
self.canvasExportStore = MiRCARTCanvasExportStore(parentCanvas=self)
self.canvasImportStore = MiRCARTCanvasImportStore(parentCanvas=self)
self.canvasInterface = MiRCARTCanvasInterface(self, parentFrame)
# Bind event handlers
self.Bind(wx.EVT_CLOSE, self.onPanelClose)
self.Bind(wx.EVT_ENTER_WINDOW, self.onPanelEnterWindow)
self.Bind(wx.EVT_LEAVE_WINDOW, self.onPanelLeaveWindow)
self.parentFrame.Bind(wx.EVT_CHAR, self.onPanelInput)
for eventType in( \
wx.EVT_LEFT_DOWN, wx.EVT_MOTION, wx.EVT_RIGHT_DOWN):
self.Bind(eventType, self.onPanelInput)
self.Bind(wx.EVT_PAINT, self.onPanelPaint)
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,175 +0,0 @@
#!/usr/bin/env python3
#
# MiRCARTCanvasBackend.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.
#
from MiRCARTColours import MiRCARTColours
import wx
class MiRCARTCanvasBackend():
"""XXX"""
_font = _brushes = _pens = None
_lastBrush = _lastPen = None
canvasBitmap = cellSize = None
# {{{ _drawBrushPatch(self, eventDc, patch): XXX
def _drawBrushPatch(self, eventDc, patch):
absPoint = self._xlatePoint(patch)
brushFg = self._brushes[patch[3]]
brushBg = self._brushes[patch[2]]
pen = self._pens[patch[3]]
self._setBrushDc(brushBg, brushFg, eventDc, pen)
eventDc.DrawRectangle(*absPoint, *self.cellSize)
# }}}
# {{{ _drawCharPatch(self, eventDc, patch): XXX
def _drawCharPatch(self, eventDc, patch):
absPoint = self._xlatePoint(patch)
brushFg = self._brushes[patch[2]]
brushBg = self._brushes[patch[3]]
pen = self._pens[patch[3]]
fontBitmap = wx.Bitmap(*self.cellSize)
fontDc = wx.MemoryDC(); fontDc.SelectObject(fontBitmap);
fontDc.SetTextForeground(wx.Colour(MiRCARTColours[patch[2]][0:4]))
fontDc.SetTextBackground(wx.Colour(MiRCARTColours[patch[3]][0:4]))
fontDc.SetBrush(brushBg); fontDc.SetBackground(brushBg); fontDc.SetPen(pen);
fontDc.SetFont(self._font)
fontDc.DrawRectangle(0, 0, *self.cellSize)
fontDc.DrawText(patch[5], 0, 0)
eventDc.Blit(*absPoint, *self.cellSize, fontDc, 0, 0)
# }}}
# {{{ _finiBrushesAndPens(self): XXX
def _finiBrushesAndPens(self):
for brush in self._brushes or []:
brush.Destroy()
self._brushes = None
for pen in self._pens or []:
pen.Destroy()
self._pens = None
self._lastBrushBg = self._lastBrushFg = self._lastPen = None;
# }}}
# {{{ _initBrushesAndPens(self): XXX
def _initBrushesAndPens(self):
self._brushes = [None for x in range(len(MiRCARTColours))]
self._pens = [None for x in range(len(MiRCARTColours))]
for mircColour in range(len(MiRCARTColours)):
self._brushes[mircColour] = wx.Brush( \
wx.Colour(MiRCARTColours[mircColour][0:4]), wx.BRUSHSTYLE_SOLID)
self._pens[mircColour] = wx.Pen( \
wx.Colour(MiRCARTColours[mircColour][0:4]), 1)
self._lastBrushBg = self._lastBrushFg = self._lastPen = None;
# }}}
# {{{ _setBrushDc(self, brushBg, brushFg, dc, pen): XXX
def _setBrushDc(self, brushBg, brushFg, dc, pen):
if self._lastBrushBg != brushBg:
dc.SetBackground(brushBg)
self._lastBrushBg = brushBg
if self._lastBrushFg != brushFg:
dc.SetBrush(brushFg)
self._lastBrushFg = brushFg
if self._lastPen != pen:
dc.SetPen(pen)
self._lastPen = pen
# }}}
# {{{ _xlatePoint(self, patch): XXX
def _xlatePoint(self, patch):
return [a*b for a,b in zip(patch[0:2], self.cellSize)]
# }}}
# {{{ drawPatch(self, eventDc, patch): XXX
def drawPatch(self, eventDc, patch):
if patch[0] < self.canvasSize[0] \
and patch[0] >= 0 \
and patch[1] < self.canvasSize[1] \
and patch[1] >= 0:
if patch[5] == " ":
self._drawBrushPatch(eventDc, patch)
else:
self._drawCharPatch(eventDc, patch)
return True
else:
return False
# }}}
# {{{ drawCursorMaskWithJournal(self, canvasJournal, eventDc): XXX
def drawCursorMaskWithJournal(self, canvasJournal, eventDc):
for patch in canvasJournal.popCursor():
self.drawPatch(eventDc, patch)
# }}}
# {{{ getDeviceContext(self, parentWindow): XXX
def getDeviceContext(self, parentWindow):
eventDc = wx.BufferedDC( \
wx.ClientDC(parentWindow), self.canvasBitmap)
self._lastBrushBg = self._lastBrushFg = self._lastPen = None;
return eventDc
# }}}
# {{{ onPanelPaintEvent(self, panelWindow, panelEvent): XXX
def onPanelPaintEvent(self, panelWindow, panelEvent):
if self.canvasBitmap != None:
eventDc = wx.BufferedPaintDC(panelWindow, self.canvasBitmap)
# }}}
# {{{ reset(self, canvasSize, cellSize):
def reset(self, canvasSize, cellSize):
self.resize(canvasSize, cellSize)
# }}}
# {{{ resize(self, canvasSize, cellSize):
def resize(self, canvasSize, cellSize):
winSize = [a*b for a,b in zip(canvasSize, cellSize)]
if self.canvasBitmap == None:
self.canvasBitmap = wx.Bitmap(winSize)
else:
oldDc = wx.MemoryDC()
oldDc.SelectObject(self.canvasBitmap)
newDc = wx.MemoryDC()
newBitmap = wx.Bitmap(winSize)
newDc.SelectObject(newBitmap)
newDc.Blit(0, 0, *self.canvasBitmap.GetSize(), oldDc, 0, 0)
oldDc.SelectObject(wx.NullBitmap)
self.canvasBitmap.Destroy(); self.canvasBitmap = newBitmap;
self.canvasSize = canvasSize; self.cellSize = cellSize;
self._font = wx.Font( \
8, \
wx.FONTFAMILY_TELETYPE, \
wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
# }}}
# {{{ xlateEventPoint(self, event, eventDc): XXX
def xlateEventPoint(self, event, eventDc):
eventPoint = event.GetLogicalPosition(eventDc)
rectX = eventPoint.x - (eventPoint.x % self.cellSize[0])
rectY = eventPoint.y - (eventPoint.y % self.cellSize[1])
mapX = int(rectX / self.cellSize[0] if rectX else 0)
mapY = int(rectY / self.cellSize[1] if rectY else 0)
return (mapX, mapY)
# }}}
# {{{ __del__(self): destructor method
def __del__(self):
if self.canvasBitmap != None:
self.canvasBitmap.Destroy(); self.canvasBitmap = None;
self._finiBrushesAndPens()
# }}}
#
# __init__(self, canvasSize, cellSize): initialisation method
def __init__(self, canvasSize, cellSize):
self._initBrushesAndPens()
self.reset(canvasSize, cellSize)
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,129 +0,0 @@
#!/usr/bin/env python3
#
# MiRCARTCanvasExportStore.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 io, os, tempfile
try:
from MiRCARTToPngFile import MiRCARTToPngFile
haveMiRCARTToPngFile = True
except ImportError:
haveMiRCARTToPngFile = False
try:
import base64, json, requests, urllib.request
haveUrllib = True
except ImportError:
haveUrllib = False
class MiRCARTCanvasExportStore():
"""XXX"""
parentCanvas = None
# {{{ _exportFileToImgur(self, apiKey, imgName, imgTitle, pathName): upload single PNG file to Imgur
def _exportFileToImgur(self, apiKey, imgName, imgTitle, pathName):
with open(pathName, "rb") as requestImage:
requestImageData = requestImage.read()
requestData = { \
"image": base64.b64encode(requestImageData), \
"key": apiKey, \
"name": imgName, \
"title": imgTitle, \
"type": "base64"}
requestHeaders = {"Authorization": "Client-ID " + apiKey}
responseHttp = requests.post( \
"https://api.imgur.com/3/upload.json", \
data=requestData, headers=requestHeaders)
responseDict = json.loads(responseHttp.text)
if responseHttp.status_code == 200:
return [200, responseDict.get("data").get("link")]
else:
return [responseHttp.status_code, ""]
# }}}
# {{{ exportBitmapToPngFile(self, canvasBitmap, outPathName, outType): XXX
def exportBitmapToPngFile(self, canvasBitmap, outPathName, outType):
return canvasBitmap.ConvertToImage().SaveFile(outPathName, outType)
# }}}
# {{{ exportBitmapToImgur(self, apiKey, canvasBitmap, imgName, imgTitle, imgType): XXX
def exportBitmapToImgur(self, apiKey, canvasBitmap, imgName, imgTitle, imgType):
tmpPathName = tempfile.mkstemp()
os.close(tmpPathName[0])
canvasBitmap.ConvertToImage().SaveFile(tmpPathName[1], imgType)
imgurResult = self._exportFileToImgur(apiKey, imgName, imgTitle, tmpPathName[1])
os.remove(tmpPathName[1])
return imgurResult
# }}}
# {{{ 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(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/api/api_post.php", \
data=requestData)
if responseHttp.status_code == 200:
if responseHttp.text.startswith("http"):
return (True, responseHttp.text)
else:
return (False, responseHttp.text)
else:
return (False, str(responseHttp.status_code))
else:
return (False, "missing requests and/or urllib3 module(s)")
# }}}
# {{{ exportPngFile(self, canvasMap, outPathName): XXX
def exportPngFile(self, canvasMap, outPathName):
if haveMiRCARTToPngFile:
MiRCARTToPngFile(canvasMap).export(outPathName)
return True
else:
return False
# }}}
# {{{ exportTextFile(self, canvasMap, canvasSize, outFile): XXX
def exportTextFile(self, canvasMap, canvasSize, outFile):
for canvasRow in range(canvasSize[1]):
canvasLastColours = []
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")
# }}}
#
# __init__(self, parentCanvas): initialisation method
def __init__(self, parentCanvas):
self.parentCanvas = parentCanvas
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,353 +0,0 @@
#!/usr/bin/env python3
#
# MiRCARTCanvasInterface.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.
#
from MiRCARTToolCircle import MiRCARTToolCircle
from MiRCARTToolFill import MiRCARTToolFill
from MiRCARTToolLine import MiRCARTToolLine
from MiRCARTToolSelectClone import MiRCARTToolSelectClone
from MiRCARTToolSelectMove import MiRCARTToolSelectMove
from MiRCARTToolRect import MiRCARTToolRect
from MiRCARTToolText import MiRCARTToolText
import os, wx
class MiRCARTCanvasInterface():
"""XXX"""
imgurApiKey = None
parentCanvas = parentFrame = canvasPathName = canvasTool = None
# {{{ _dialogSaveChanges(self)
def _dialogSaveChanges(self):
with wx.MessageDialog(self.parentCanvas, \
"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
# }}}
# {{{ canvasBrushSolid(self, event): XXX
def canvasBrushSolid(self, event):
pass
# }}}
# {{{ canvasColour(self, event, numColour): XXX
def canvasColour(self, event, numColour):
if event.GetEventType() == wx.wxEVT_TOOL:
self.parentCanvas.brushColours[0] = numColour
elif event.GetEventType() == wx.wxEVT_TOOL_RCLICKED:
self.parentCanvas.brushColours[1] = numColour
self.parentFrame.onCanvasUpdate(colours=self.parentCanvas.brushColours)
# }}}
# {{{ canvasCopy(self, event): XXX
def canvasCopy(self, event):
pass
# }}}
# {{{ canvasCut(self, event): XXX
def canvasCut(self, event):
pass
# }}}
# {{{ canvasDecrBrushHeight(self, event): XXX
def canvasDecrBrushHeight(self, event):
if self.parentCanvas.brushSize[1] > 1:
self.parentCanvas.brushSize[1] -= 1
self.parentFrame.onCanvasUpdate(brushSize=self.parentCanvas.brushSize)
# }}}
# {{{ canvasDecrBrushHeightWidth(self, event): XXX
def canvasDecrBrushHeightWidth(self, event):
self.canvasDecrBrushHeight(event)
self.canvasDecrBrushWidth(event)
# }}}
# {{{ canvasDecrBrushWidth(self, event): XXX
def canvasDecrBrushWidth(self, event):
if self.parentCanvas.brushSize[0] > 1:
self.parentCanvas.brushSize[0] -= 1
self.parentFrame.onCanvasUpdate(brushSize=self.parentCanvas.brushSize)
# }}}
# {{{ canvasDecrCanvasHeight(self, event): XXX
def canvasDecrCanvasHeight(self, event):
if self.parentCanvas.canvasSize[1] > 1:
self.parentCanvas.resize([ \
self.parentCanvas.canvasSize[0], \
self.parentCanvas.canvasSize[1]-1])
# }}}
# {{{ canvasDecrCanvasHeightWidth(self, event): XXX
def canvasDecrCanvasHeightWidth(self, event):
self.canvasDecrCanvasHeight(event)
self.canvasDecrCanvasWidth(event)
# }}}
# {{{ canvasDecrCanvasWidth(self, event): XXX
def canvasDecrCanvasWidth(self, event):
if self.parentCanvas.canvasSize[0] > 1:
self.parentCanvas.resize([ \
self.parentCanvas.canvasSize[0]-1, \
self.parentCanvas.canvasSize[1]])
# }}}
# {{{ canvasDelete(self, event): XXX
def canvasDelete(self, event):
pass
# }}}
# {{{ canvasExit(self, event): XXX
def canvasExit(self, event):
if self.canvasPathName != None:
saveChanges = self._dialogSaveChanges()
if saveChanges == wx.ID_CANCEL:
return
elif saveChanges == wx.ID_NO:
pass
elif saveChanges == wx.ID_YES:
self.canvasSave(event)
self.parentFrame.Close(True)
# }}}
# {{{ canvasExportAsPng(self, event): XXX
def canvasExportAsPng(self, event):
with wx.FileDialog(self, "Save As...", os.getcwd(), "", \
"*.png", wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) as dialog:
if dialog.ShowModal() == wx.ID_CANCEL:
return False
else:
outPathName = dialog.GetPath()
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
self.parentCanvas.canvasExportStore.exportBitmapToPngFile( \
self.parentCanvas.canvasBackend.canvasBitmap, outPathName, \
wx.BITMAP_TYPE_PNG)
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
return True
# }}}
# {{{ canvasExportImgur(self, event): XXX
def canvasExportImgur(self, event):
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
imgurResult = self.parentCanvas.canvasExportStore.exportBitmapToImgur( \
self.imgurApiKey, self.parentCanvas.canvasBackend.canvasBitmap, \
"", "", wx.BITMAP_TYPE_PNG)
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
if imgurResult[0] == 200:
if not wx.TheClipboard.IsOpened():
wx.TheClipboard.Open()
wx.TheClipboard.SetData(wx.TextDataObject(imgurResult[1]))
wx.TheClipboard.Close()
wx.MessageBox("Exported to Imgur: " + imgurResult[1], \
"Export to Imgur", wx.OK|wx.ICON_INFORMATION)
else:
wx.MessageBox("Failed to export to Imgur: " + imgurResult[1], \
"Export to Imgur", wx.OK|wx.ICON_EXCLAMATION)
# }}}
# {{{ canvasExportPastebin(self, event): XXX
def canvasExportPastebin(self, event):
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
pasteStatus, pasteResult = \
self.parentCanvas.canvasExportStore.exportPastebin( \
"", \
self.parentCanvas.canvasMap, \
self.parentCanvas.canvasSize)
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
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)
# }}}
# {{{ canvasIncrBrushHeight(self, event): XXX
def canvasIncrBrushHeight(self, event):
self.parentCanvas.brushSize[1] += 1
self.parentFrame.onCanvasUpdate(brushSize=self.parentCanvas.brushSize)
# }}}
# {{{ canvasIncrBrushHeightWidth(self, event): XXX
def canvasIncrBrushHeightWidth(self, event):
self.canvasIncrBrushHeight(event)
self.canvasIncrBrushWidth(event)
# }}}
# {{{ canvasIncrBrushWidth(self, event): XXX
def canvasIncrBrushWidth(self, event):
self.parentCanvas.brushSize[0] += 1
self.parentFrame.onCanvasUpdate(brushSize=self.parentCanvas.brushSize)
# }}}
# {{{ canvasIncrCanvasHeight(self, event): XXX
def canvasIncrCanvasHeight(self, event):
self.parentCanvas.resize([ \
self.parentCanvas.canvasSize[0], \
self.parentCanvas.canvasSize[1]+1])
# }}}
# {{{ canvasIncrCanvasHeightWidth(self, event): XXX
def canvasIncrCanvasHeightWidth(self, event):
self.canvasIncrCanvasHeight(event)
self.canvasIncrCanvasWidth(event)
# }}}
# {{{ canvasIncrCanvasWidth(self, event): XXX
def canvasIncrCanvasWidth(self, event):
self.parentCanvas.resize([ \
self.parentCanvas.canvasSize[0]+1, \
self.parentCanvas.canvasSize[1]])
# }}}
# {{{ canvasNew(self, event, newCanvasSize=None): XXX
def canvasNew(self, event, newCanvasSize=None):
if self.canvasPathName != None:
saveChanges = self._dialogSaveChanges()
if saveChanges == wx.ID_CANCEL:
return
elif saveChanges == wx.ID_NO:
pass
elif saveChanges == wx.ID_YES:
self.canvasSave(event)
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
if newCanvasSize == None:
newCanvasSize = list(self.parentCanvas.defaultCanvasSize)
self.parentCanvas.canvasImportStore.importNew(newCanvasSize)
self.canvasPathName = None
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
self.parentFrame.onCanvasUpdate(pathName="", undoLevel=-1)
# }}}
# {{{ canvasOpen(self, event): XXX
def canvasOpen(self, event):
if self.canvasPathName != None:
saveChanges = self._dialogSaveChanges()
if saveChanges == wx.ID_CANCEL:
return
elif saveChanges == wx.ID_NO:
pass
elif saveChanges == wx.ID_YES:
self.canvasSave(event)
with wx.FileDialog(self.parentCanvas, "Open", os.getcwd(), "", \
"*.txt", wx.FD_OPEN) as dialog:
if dialog.ShowModal() == wx.ID_CANCEL:
return False
else:
self.canvasPathName = dialog.GetPath()
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
self.parentCanvas.canvasImportStore.importTextFile(self.canvasPathName)
self.parentCanvas.canvasImportStore.importIntoPanel()
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
self.parentFrame.onCanvasUpdate( \
pathName=self.canvasPathName, undoLevel=-1)
return True
# }}}
# {{{ canvasPaste(self, event): XXX
def canvasPaste(self, event):
pass
# }}}
# {{{ canvasRedo(self, event): XXX
def canvasRedo(self, event):
self.parentCanvas._dispatchDeltaPatches( \
self.parentCanvas.canvasJournal.popRedo())
# }}}
# {{{ canvasSave(self, event): XXX
def canvasSave(self, event):
if self.canvasPathName == None:
if self.canvasSaveAs(event) == False:
return
try:
with open(self.canvasPathName, "w") as outFile:
self.parentCanvas.SetCursor(wx.Cursor(wx.CURSOR_WAIT))
self.parentCanvas.canvasExportStore.exportTextFile( \
self.parentCanvas.canvasMap, \
self.parentCanvas.canvasSize, outFile)
self.parentCanvas.SetCursor(wx.Cursor(wx.NullCursor))
return True
except IOError as error:
return False
# }}}
# {{{ canvasSaveAs(self, event): XXX
def canvasSaveAs(self, event):
with wx.FileDialog(self.parentCanvas, "Save As", os.getcwd(), "", \
"*.txt", wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT) as dialog:
if dialog.ShowModal() == wx.ID_CANCEL:
return False
else:
self.canvasPathName = dialog.GetPath()
return self.canvasSave(event)
# }}}
# {{{ canvasToolCircle(self, event): XXX
def canvasToolCircle(self, event):
self.canvasTool = MiRCARTToolCircle(self.parentCanvas)
self.parentFrame.menuItemsById[self.parentFrame.CID_CIRCLE[0]].Check(True)
toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_CIRCLE[0]].GetToolBar()
toolBar.ToggleTool(self.parentFrame.CID_CIRCLE[0], True)
self.parentFrame.onCanvasUpdate(toolName=self.canvasTool.name)
# }}}
# {{{ canvasToolFill(self, event): XXX
def canvasToolFill(self, event):
self.canvasTool = MiRCARTToolFill(self.parentCanvas)
self.parentFrame.menuItemsById[self.parentFrame.CID_FILL[0]].Check(True)
toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_FILL[0]].GetToolBar()
toolBar.ToggleTool(self.parentFrame.CID_FILL[0], True)
self.parentFrame.onCanvasUpdate(toolName=self.canvasTool.name)
# }}}
# {{{ canvasToolLine(self, event): XXX
def canvasToolLine(self, event):
self.canvasTool = MiRCARTToolLine(self.parentCanvas)
self.parentFrame.menuItemsById[self.parentFrame.CID_LINE[0]].Check(True)
toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_LINE[0]].GetToolBar()
toolBar.ToggleTool(self.parentFrame.CID_LINE[0], True)
self.parentFrame.onCanvasUpdate(toolName=self.canvasTool.name)
# }}}
# {{{ canvasToolSelectClone(self, event): XXX
def canvasToolSelectClone(self, event):
self.canvasTool = MiRCARTToolSelectClone(self.parentCanvas)
self.parentFrame.menuItemsById[self.parentFrame.CID_CLONE_SELECT[0]].Check(True)
toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_CLONE_SELECT[0]].GetToolBar()
toolBar.ToggleTool(self.parentFrame.CID_CLONE_SELECT[0], True)
self.parentFrame.onCanvasUpdate(toolName=self.canvasTool.name)
# }}}
# {{{ canvasToolSelectMove(self, event): XXX
def canvasToolSelectMove(self, event):
self.canvasTool = MiRCARTToolSelectMove(self.parentCanvas)
self.parentFrame.menuItemsById[self.parentFrame.CID_MOVE_SELECT[0]].Check(True)
toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_MOVE_SELECT[0]].GetToolBar()
toolBar.ToggleTool(self.parentFrame.CID_MOVE_SELECT[0], True)
self.parentFrame.onCanvasUpdate(toolName=self.canvasTool.name)
# }}}
# {{{ canvasToolRect(self, event): XXX
def canvasToolRect(self, event):
self.canvasTool = MiRCARTToolRect(self.parentCanvas)
self.parentFrame.menuItemsById[self.parentFrame.CID_RECT[0]].Check(True)
toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_RECT[0]].GetToolBar()
toolBar.ToggleTool(self.parentFrame.CID_RECT[0], True)
self.parentFrame.onCanvasUpdate(toolName=self.canvasTool.name)
# }}}
# {{{ canvasToolText(self, event): XXX
def canvasToolText(self, event):
self.canvasTool = MiRCARTToolText(self.parentCanvas)
self.parentFrame.menuItemsById[self.parentFrame.CID_TEXT[0]].Check(True)
toolBar = self.parentFrame.toolBarItemsById[self.parentFrame.CID_TEXT[0]].GetToolBar()
toolBar.ToggleTool(self.parentFrame.CID_TEXT[0], True)
self.parentFrame.onCanvasUpdate(toolName=self.canvasTool.name)
# }}}
# {{{ canvasUndo(self, event): XXX
def canvasUndo(self, event):
self.parentCanvas._dispatchDeltaPatches( \
self.parentCanvas.canvasJournal.popUndo())
# }}}
#
# __init__(self, parentCanvas, parentFrame):
def __init__(self, parentCanvas, parentFrame):
self.parentCanvas = parentCanvas; self.parentFrame = parentFrame;
self.canvasPathName = None
self.canvasToolRect(None)
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,97 +0,0 @@
#!/usr/bin/env python3
#
# MiRCARTCanvasJournal.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.
#
class MiRCARTCanvasJournal():
"""XXX"""
patchesCursor = patchesUndo = patchesUndoLevel = None
# {{{ popCursor(self): XXX
def popCursor(self):
if len(self.patchesCursor):
patchesCursor = self.patchesCursor
self.patchesCursor = []
return patchesCursor
else:
return []
# }}}
# {{{ popRedo(self): XXX
def popRedo(self):
if self.patchesUndoLevel > 0:
self.patchesUndoLevel -= 1
patches = self.patchesUndo[self.patchesUndoLevel]
return patches[1]
else:
return []
# }}}
# {{{ popUndo(self): XXX
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): XXX
def pushCursor(self, patches):
self.patchesCursor.append(patches)
# }}}
# {{{ pushDeltas(self, undoPatches, redoPatches): XXX
def pushDeltas(self, undoPatches, redoPatches):
if self.patchesUndoLevel > 0:
del self.patchesUndo[0:self.patchesUndoLevel]
self.patchesUndoLevel = 0
deltaItem = [undoPatches, redoPatches]
self.patchesUndo.insert(0, deltaItem)
return deltaItem
# }}}
# {{{ resetCursor(self): XXX
def resetCursor(self):
if self.patchesCursor != None:
self.patchesCursor.clear()
self.patchesCursor = []
# }}}
# {{{ resetUndo(self): XXX
def resetUndo(self):
if self.patchesUndo != None:
self.patchesUndo.clear()
self.patchesUndo = [None]; self.patchesUndoLevel = 0;
# }}}
# {{{ updateCurrentDeltas(self, undoPatches, redoPatches): XXX
def updateCurrentDeltas(self, undoPatches, redoPatches):
self.patchesUndo[0][0].append(undoPatches)
self.patchesUndo[0][1].append(redoPatches)
# }}}
# {{{ __del__(self): destructor method
def __del__(self):
self.resetCursor(); self.resetUndo();
# }}}
#
# __init__(self): initialisation method
def __init__(self):
self.resetCursor(); self.resetUndo();
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,33 +0,0 @@
#!/bin/sh
#
# MiRCARTCheckLineLengths.py -- check mIRC art line lengths
# 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.
for FNAME in "${@}"; do
FNAME_LINES="$(wc -l "${FNAME}" | awk '{print $1}')";
for FNAME_LINE in $(seq "${FNAME_LINES}"); do
printf "%-5d %-5d %s\n" \
"$(sed -n "${FNAME_LINE}p" "${FNAME}" | wc -c)" \
"${FNAME_LINE}" "${FNAME}";
done;
done | sort -nk1;
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,47 +0,0 @@
#!/usr/bin/env python3
#
# MiRCARTColours.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.
#
#
# 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"],
]
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,252 +0,0 @@
#!/usr/bin/env python3
#
# MiRCARTFrame.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.
#
from MiRCARTCanvas import MiRCARTCanvas, haveUrllib
from MiRCARTCanvasInterface import MiRCARTCanvasInterface
from MiRCARTColours import MiRCARTColours
from MiRCARTGeneralFrame import MiRCARTGeneralFrame, \
TID_ACCELS, TID_COMMAND, TID_LIST, TID_MENU, TID_NOTHING, TID_SELECT, TID_TOOLBAR, \
NID_MENU_SEP, NID_TOOLBAR_HSEP, NID_TOOLBAR_VSEP
import os, wx
class MiRCARTFrame(MiRCARTGeneralFrame):
"""XXX"""
panelCanvas = None; lastPanelState = {};
# {{{ Commands
# Id Type Id Labels Icon bitmap Accelerator [Initial state]
CID_NEW = [0x100, TID_COMMAND, "New", "&New", ["", wx.ART_NEW], [wx.ACCEL_CTRL, ord("N")], None, MiRCARTCanvasInterface.canvasNew]
CID_OPEN = [0x101, TID_COMMAND, "Open", "&Open", ["", wx.ART_FILE_OPEN], [wx.ACCEL_CTRL, ord("O")], None, MiRCARTCanvasInterface.canvasOpen]
CID_SAVE = [0x102, TID_COMMAND, "Save", "&Save", ["", wx.ART_FILE_SAVE], [wx.ACCEL_CTRL, ord("S")], None, MiRCARTCanvasInterface.canvasSave]
CID_SAVEAS = [0x103, TID_COMMAND, "Save As...", "Save &As...", ["", wx.ART_FILE_SAVE_AS], None, None, MiRCARTCanvasInterface.canvasSaveAs]
CID_EXPORT_AS_PNG = [0x104, TID_COMMAND, "Export as PNG...", \
"Export as PN&G...", None, None, None, MiRCARTCanvasInterface.canvasExportAsPng]
CID_EXPORT_IMGUR = [0x105, TID_COMMAND, "Export to Imgur...", \
"Export to I&mgur...", None, None, haveUrllib, MiRCARTCanvasInterface.canvasExportImgur]
CID_EXPORT_PASTEBIN = [0x106, TID_COMMAND, "Export to Pastebin...", \
"Export to Pasteb&in...", None, None, haveUrllib, MiRCARTCanvasInterface.canvasExportPastebin]
CID_EXIT = [0x107, TID_COMMAND, "Exit", "E&xit", None, [wx.ACCEL_CTRL, ord("X")], None, MiRCARTCanvasInterface.canvasExit]
CID_UNDO = [0x108, TID_COMMAND, "Undo", "&Undo", ["", wx.ART_UNDO], [wx.ACCEL_CTRL, ord("Z")], False, MiRCARTCanvasInterface.canvasUndo]
CID_REDO = [0x109, TID_COMMAND, "Redo", "&Redo", ["", wx.ART_REDO], [wx.ACCEL_CTRL, ord("Y")], False, MiRCARTCanvasInterface.canvasRedo]
CID_CUT = [0x10a, TID_COMMAND, "Cut", "Cu&t", ["", wx.ART_CUT], None, False, MiRCARTCanvasInterface.canvasCut]
CID_COPY = [0x10b, TID_COMMAND, "Copy", "&Copy", ["", wx.ART_COPY], None, False, MiRCARTCanvasInterface.canvasCopy]
CID_PASTE = [0x10c, TID_COMMAND, "Paste", "&Paste", ["", wx.ART_PASTE], None, False, MiRCARTCanvasInterface.canvasPaste]
CID_DELETE = [0x10d, TID_COMMAND, "Delete", "De&lete", ["", wx.ART_DELETE], None, False, MiRCARTCanvasInterface.canvasDelete]
CID_INCRW_CANVAS = [0x10e, TID_COMMAND, "Increase canvas width", \
"Increase canvas width", ["toolIncrCanvasW.png"], None, None, MiRCARTCanvasInterface.canvasIncrCanvasWidth]
CID_DECRW_CANVAS = [0x10f, TID_COMMAND, "Decrease canvas width", \
"Decrease canvas width", ["toolDecrCanvasW.png"], None, None, MiRCARTCanvasInterface.canvasDecrCanvasWidth]
CID_INCRH_CANVAS = [0x110, TID_COMMAND, "Increase canvas height", \
"Increase canvas height", ["toolIncrCanvasH.png"], None, None, MiRCARTCanvasInterface.canvasIncrCanvasHeight]
CID_DECRH_CANVAS = [0x111, TID_COMMAND, "Decrease canvas height", \
"Decrease canvas height", ["toolDecrCanvasH.png"], None, None, MiRCARTCanvasInterface.canvasDecrCanvasHeight]
CID_INCRHW_CANVAS = [0x112, TID_COMMAND, "Increase canvas size", \
"Increase canvas size", ["toolIncrCanvasHW.png"], None, None, MiRCARTCanvasInterface.canvasIncrCanvasHeightWidth]
CID_DECRHW_CANVAS = [0x113, TID_COMMAND, "Decrease canvas size", \
"Decrease canvas size", ["toolDecrCanvasHW.png"], None, None, MiRCARTCanvasInterface.canvasDecrCanvasHeightWidth]
CID_INCRW_BRUSH = [0x114, TID_COMMAND, "Increase brush width", \
"Increase brush width", ["toolIncrBrushW.png"], None, None, MiRCARTCanvasInterface.canvasIncrBrushWidth]
CID_DECRW_BRUSH = [0x115, TID_COMMAND, "Decrease brush width", \
"Decrease brush width", ["toolDecrBrushW.png"], None, None, MiRCARTCanvasInterface.canvasDecrBrushWidth]
CID_INCRH_BRUSH = [0x116, TID_COMMAND, "Increase brush height", \
"Increase brush height", ["toolIncrBrushH.png"], None, None, MiRCARTCanvasInterface.canvasIncrBrushHeight]
CID_DECRH_BRUSH = [0x117, TID_COMMAND, "Decrease brush height", \
"Decrease brush height", ["toolDecrBrushH.png"], None, None, MiRCARTCanvasInterface.canvasDecrBrushHeight]
CID_INCRHW_BRUSH = [0x118, TID_COMMAND, "Increase brush size", \
"Increase brush size", ["toolIncrBrushHW.png"], None, None, MiRCARTCanvasInterface.canvasIncrBrushHeightWidth]
CID_DECRHW_BRUSH = [0x119, TID_COMMAND, "Decrease brush size", \
"Decrease brush size", ["toolDecrBrushHW.png"], None, None, MiRCARTCanvasInterface.canvasDecrBrushHeightWidth]
CID_SOLID_BRUSH = [0x11a, TID_SELECT, "Solid brush", "Solid brush", None, None, True, MiRCARTCanvasInterface.canvasBrushSolid]
CID_RECT = [0x150, TID_SELECT, "Rectangle", "&Rectangle", ["toolRect.png"], [wx.ACCEL_CTRL, ord("R")], True, MiRCARTCanvasInterface.canvasToolRect]
CID_CIRCLE = [0x151, TID_SELECT, "Circle", "&Circle", ["toolCircle.png"], [wx.ACCEL_CTRL, ord("C")], False, MiRCARTCanvasInterface.canvasToolCircle]
CID_FILL = [0x152, TID_SELECT, "Fill", "&Fill", ["toolFill.png"], [wx.ACCEL_CTRL, ord("F")], False, MiRCARTCanvasInterface.canvasToolFill]
CID_LINE = [0x153, TID_SELECT, "Line", "&Line", ["toolLine.png"], [wx.ACCEL_CTRL, ord("L")], False, MiRCARTCanvasInterface.canvasToolLine]
CID_TEXT = [0x154, TID_SELECT, "Text", "&Text", ["toolText.png"], [wx.ACCEL_CTRL, ord("T")], False, MiRCARTCanvasInterface.canvasToolText]
CID_CLONE_SELECT = [0x155, TID_SELECT, "Clone", "Cl&one", ["toolClone.png"], [wx.ACCEL_CTRL, ord("E")], False, MiRCARTCanvasInterface.canvasToolSelectClone]
CID_MOVE_SELECT = [0x156, TID_SELECT, "Move", "&Move", ["toolMove.png"], [wx.ACCEL_CTRL, ord("M")], False, MiRCARTCanvasInterface.canvasToolSelectMove]
CID_COLOUR00 = [0x1a0, TID_SELECT, "Colour #00", "Colour #00", None, None, False, MiRCARTCanvasInterface.canvasColour]
CID_COLOUR01 = [0x1a1, TID_SELECT, "Colour #01", "Colour #01", None, None, False, MiRCARTCanvasInterface.canvasColour]
CID_COLOUR02 = [0x1a2, TID_SELECT, "Colour #02", "Colour #02", None, None, False, MiRCARTCanvasInterface.canvasColour]
CID_COLOUR03 = [0x1a3, TID_SELECT, "Colour #03", "Colour #03", None, None, False, MiRCARTCanvasInterface.canvasColour]
CID_COLOUR04 = [0x1a4, TID_SELECT, "Colour #04", "Colour #04", None, None, True, MiRCARTCanvasInterface.canvasColour]
CID_COLOUR05 = [0x1a5, TID_SELECT, "Colour #05", "Colour #05", None, None, False, MiRCARTCanvasInterface.canvasColour]
CID_COLOUR06 = [0x1a6, TID_SELECT, "Colour #06", "Colour #06", None, None, False, MiRCARTCanvasInterface.canvasColour]
CID_COLOUR07 = [0x1a7, TID_SELECT, "Colour #07", "Colour #07", None, None, False, MiRCARTCanvasInterface.canvasColour]
CID_COLOUR08 = [0x1a8, TID_SELECT, "Colour #08", "Colour #08", None, None, False, MiRCARTCanvasInterface.canvasColour]
CID_COLOUR09 = [0x1a9, TID_SELECT, "Colour #09", "Colour #09", None, None, False, MiRCARTCanvasInterface.canvasColour]
CID_COLOUR10 = [0x1aa, TID_SELECT, "Colour #10", "Colour #10", None, None, False, MiRCARTCanvasInterface.canvasColour]
CID_COLOUR11 = [0x1ab, TID_SELECT, "Colour #11", "Colour #11", None, None, False, MiRCARTCanvasInterface.canvasColour]
CID_COLOUR12 = [0x1ac, TID_SELECT, "Colour #12", "Colour #12", None, None, False, MiRCARTCanvasInterface.canvasColour]
CID_COLOUR13 = [0x1ad, TID_SELECT, "Colour #13", "Colour #13", None, None, False, MiRCARTCanvasInterface.canvasColour]
CID_COLOUR14 = [0x1ae, TID_SELECT, "Colour #14", "Colour #14", None, None, False, MiRCARTCanvasInterface.canvasColour]
CID_COLOUR15 = [0x1af, TID_SELECT, "Colour #15", "Colour #15", None, None, False, MiRCARTCanvasInterface.canvasColour]
# }}}
# {{{ Menus
MID_FILE = (0x300, TID_MENU, "File", "&File", ( \
CID_NEW, CID_OPEN, CID_SAVE, CID_SAVEAS, NID_MENU_SEP, \
CID_EXPORT_AS_PNG, CID_EXPORT_IMGUR, CID_EXPORT_PASTEBIN, NID_MENU_SEP, \
CID_EXIT))
MID_EDIT = (0x301, TID_MENU, "Edit", "&Edit", ( \
CID_UNDO, CID_REDO, NID_MENU_SEP, \
CID_CUT, CID_COPY, CID_PASTE, CID_DELETE, NID_MENU_SEP, \
CID_INCRW_CANVAS, CID_DECRW_CANVAS, CID_INCRH_CANVAS, CID_DECRH_CANVAS, NID_MENU_SEP, \
CID_INCRHW_CANVAS, CID_DECRHW_CANVAS, NID_MENU_SEP, \
CID_INCRW_BRUSH, CID_DECRW_BRUSH, CID_INCRH_BRUSH, CID_DECRH_BRUSH, NID_MENU_SEP, \
CID_INCRHW_BRUSH, CID_DECRHW_BRUSH, NID_MENU_SEP, \
CID_SOLID_BRUSH))
MID_TOOLS = (0x302, TID_MENU, "Tools", "&Tools", ( \
CID_RECT, CID_CIRCLE, CID_FILL, CID_LINE, CID_TEXT, CID_CLONE_SELECT, CID_MOVE_SELECT))
# }}}
# {{{ Toolbars
BID_TOOLBAR = (0x400, TID_TOOLBAR, ( \
CID_NEW, CID_OPEN, CID_SAVE, CID_SAVEAS, NID_TOOLBAR_HSEP, \
CID_UNDO, CID_REDO, NID_TOOLBAR_HSEP, \
CID_CUT, CID_COPY, CID_PASTE, CID_DELETE, NID_TOOLBAR_HSEP, \
CID_INCRW_CANVAS, CID_DECRW_CANVAS, CID_INCRH_CANVAS, CID_DECRH_CANVAS, NID_TOOLBAR_HSEP, \
CID_INCRHW_CANVAS, CID_DECRHW_CANVAS, NID_TOOLBAR_HSEP, \
CID_RECT, CID_CIRCLE, CID_FILL, CID_LINE, CID_TEXT, CID_CLONE_SELECT, CID_MOVE_SELECT, \
NID_TOOLBAR_VSEP, \
CID_COLOUR00, CID_COLOUR01, CID_COLOUR02, CID_COLOUR03, CID_COLOUR04, \
CID_COLOUR05, CID_COLOUR06, CID_COLOUR07, CID_COLOUR08, CID_COLOUR09, \
CID_COLOUR10, CID_COLOUR11, CID_COLOUR12, CID_COLOUR13, CID_COLOUR14, \
CID_COLOUR15, NID_TOOLBAR_HSEP, \
CID_INCRW_BRUSH, CID_DECRW_BRUSH, CID_INCRH_BRUSH, CID_DECRH_BRUSH, NID_TOOLBAR_HSEP, \
CID_INCRHW_BRUSH, CID_DECRHW_BRUSH))
# }}}
# {{{ Accelerators (hotkeys)
AID_EDIT = (0x500, TID_ACCELS, ( \
CID_NEW, CID_OPEN, CID_SAVE, CID_EXIT, CID_UNDO, CID_REDO, \
CID_RECT, CID_CIRCLE, CID_FILL, CID_LINE, CID_TEXT, CID_CLONE_SELECT, CID_MOVE_SELECT))
# }}}
# {{{ Lists
LID_ACCELS = (0x600, TID_LIST, (AID_EDIT))
LID_MENUS = (0x601, TID_LIST, (MID_FILE, MID_EDIT, MID_TOOLS))
LID_TOOLBARS = (0x602, TID_LIST, (BID_TOOLBAR))
# }}}
# {{{ _initPaletteToolBitmaps(self): XXX
def _initPaletteToolBitmaps(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)
paletteDescr[numColour][4] = ["", None, toolBitmap]
# }}}
# {{{ onInput(self, event): XXX
def onInput(self, event):
eventId = event.GetId()
if eventId >= self.CID_COLOUR00[0] \
and eventId <= self.CID_COLOUR15[0]:
numColour = eventId - self.CID_COLOUR00[0]
self.itemsById[eventId][7](self.panelCanvas.canvasInterface, event, numColour)
else:
self.itemsById[eventId][7](self.panelCanvas.canvasInterface, event)
# }}}
# {{{ onCanvasUpdate(self, newBrushSize=None, newCellPos=None, newColours=None, newPathName=None, newSize=None, newToolName=None, newUndoLevel=None): XXX
def onCanvasUpdate(self, **kwargs):
self.lastPanelState.update(kwargs)
textItems = []
if "cellPos" in self.lastPanelState:
textItems.append("X: {:03d} Y: {:03d}".format( \
*self.lastPanelState["cellPos"]))
if "size" in self.lastPanelState:
textItems.append("W: {:03d} H: {:03d}".format( \
*self.lastPanelState["size"]))
if "brushSize" in self.lastPanelState:
textItems.append("Brush: {:02d}x{:02d}".format( \
*self.lastPanelState["brushSize"]))
if "colours" in self.lastPanelState:
textItems.append("FG: {:02d}, BG: {:02d}".format( \
*self.lastPanelState["colours"]))
textItems.append("{} on {}".format( \
MiRCARTColours[self.lastPanelState["colours"][0]][4], \
MiRCARTColours[self.lastPanelState["colours"][1]][4]))
if "pathName" in self.lastPanelState:
if self.lastPanelState["pathName"] != "":
basePathName = os.path.basename(self.lastPanelState["pathName"])
textItems.append("Current file: {}".format(basePathName))
self.SetTitle("{} - MiRCART".format(basePathName))
else:
self.SetTitle("MiRCART")
if "toolName" in self.lastPanelState:
textItems.append("Current tool: {}".format( \
self.lastPanelState["toolName"]))
self.statusBar.SetStatusText(" | ".join(textItems))
if "undoLevel" in self.lastPanelState:
if self.lastPanelState["undoLevel"] >= 0:
self.menuItemsById[self.CID_UNDO[0]].Enable(True)
toolBar = self.toolBarItemsById[self.CID_UNDO[0]].GetToolBar()
toolBar.EnableTool(self.CID_UNDO[0], True)
else:
self.menuItemsById[self.CID_UNDO[0]].Enable(False)
toolBar = self.toolBarItemsById[self.CID_UNDO[0]].GetToolBar()
toolBar.EnableTool(self.CID_UNDO[0], False)
if self.lastPanelState["undoLevel"] > 0:
self.menuItemsById[self.CID_REDO[0]].Enable(True)
toolBar = self.toolBarItemsById[self.CID_REDO[0]].GetToolBar()
toolBar.EnableTool(self.CID_REDO[0], True)
else:
self.menuItemsById[self.CID_REDO[0]].Enable(False)
toolBar = self.toolBarItemsById[self.CID_REDO[0]].GetToolBar()
toolBar.EnableTool(self.CID_REDO[0], False)
# }}}
# {{{ __del__(self): destructor method
def __del__(self):
if self.panelCanvas != None:
del self.panelCanvas; self.panelCanvas = None;
# }}}
#
# __init__(self, parent, appSize=(840, 630), defaultCanvasPos=(0, 75), defaultCanvasSize=(100, 30), defaultCellSize=(7, 14)): initialisation method
def __init__(self, parent, appSize=(840, 630), defaultCanvasPos=(0, 75), defaultCanvasSize=(100, 30), defaultCellSize=(7, 14)):
self._initPaletteToolBitmaps()
self.panelSkin = super().__init__(parent, wx.ID_ANY, "MiRCART", size=appSize)
self.panelCanvas = MiRCARTCanvas(self.panelSkin, parentFrame=self, \
defaultCanvasPos=defaultCanvasPos, \
defaultCanvasSize=defaultCanvasSize, \
defaultCellSize=defaultCellSize)
self.panelCanvas.canvasInterface.canvasNew(None)
self.sizerSkin.AddSpacer(5)
self.sizerSkin.Add(self.panelCanvas, 0, wx.ALL|wx.EXPAND, 14)
self.panelSkin.SetSizer(self.sizerSkin)
self.panelSkin.SetAutoLayout(1)
self.sizerSkin.Fit(self.panelSkin)
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,187 +0,0 @@
#!/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, sys, wx
#
# Types
TID_ACCELS = (0x001)
TID_COMMAND = (0x002)
TID_LIST = (0x003)
TID_MENU = (0x004)
TID_NOTHING = (0x005)
TID_SELECT = (0x006)
TID_TOOLBAR = (0x007)
#
# Non-items
NID_MENU_SEP = (0x200, TID_NOTHING)
NID_TOOLBAR_HSEP = (0x201, TID_NOTHING)
NID_TOOLBAR_VSEP = (0x202, TID_NOTHING)
class MiRCARTGeneralFrame(wx.Frame):
"""XXX"""
accelItemsById = itemsById = menuItemsById = toolBarItemsById = None
statusBar = toolBars = None
panelSkin = sizerSkin = None
# {{{ _initAccelTable(self, accelsDescr): XXX
def _initAccelTable(self, accelsDescr):
accelTableEntries = [wx.AcceleratorEntry() for n in range(len(accelsDescr[2]))]
self.accelItemsById = {}
for numAccel in range(len(accelsDescr[2])):
accelDescr = accelsDescr[2][numAccel]
if accelDescr[5] != None:
self.itemsById[accelDescr[0]] = accelDescr
accelTableEntries[numAccel].Set(*accelDescr[5], accelDescr[0])
self.accelItemsById[accelDescr[0]] = accelTableEntries[numAccel]
self.Bind(wx.EVT_MENU, self.onInput, id=accelDescr[0])
return accelTableEntries
# }}}
# {{{ _initMenus(self, menusDescr): XXX
def _initMenus(self, menusDescr):
self.menuItemsById = {}; menuBar = wx.MenuBar();
for menuDescr in menusDescr:
menuWindow = wx.Menu()
for menuItem in menuDescr[4]:
if menuItem == NID_MENU_SEP:
menuWindow.AppendSeparator()
elif menuItem[1] == TID_SELECT:
self.itemsById[menuItem[0]] = menuItem
menuItemWindow = menuWindow.AppendRadioItem(menuItem[0], menuItem[3], menuItem[2])
if menuItem[5] != None:
menuItemWindow.SetAccel(self.accelItemsById[menuItem[0]])
self.menuItemsById[menuItem[0]] = menuItemWindow
self.Bind(wx.EVT_MENU, self.onInput, menuItemWindow)
if menuItem[6] != None:
menuItemWindow.Check(menuItem[6])
else:
self.itemsById[menuItem[0]] = menuItem
menuItemWindow = menuWindow.Append(menuItem[0], menuItem[3], menuItem[2])
if menuItem[5] != None:
menuItemWindow.SetAccel(self.accelItemsById[menuItem[0]])
self.menuItemsById[menuItem[0]] = menuItemWindow
self.Bind(wx.EVT_MENU, self.onInput, menuItemWindow)
if menuItem[6] != None:
menuItemWindow.Enable(menuItem[6])
menuBar.Append(menuWindow, menuDescr[3])
return menuBar
# }}}
# {{{ _initToolBars(self, toolBarsDescr, panelSkin): XXX
def _initToolBars(self, toolBarsDescr, panelSkin):
self.toolBarItemsById = {}
self.sizerSkin = wx.BoxSizer(wx.VERTICAL)
self.toolBars = [None]; numToolBar = 0;
for toolBarItem in toolBarsDescr[2]:
if self.toolBars[numToolBar] == None:
self.toolBars[numToolBar] = \
wx.ToolBar(panelSkin, -1, \
style=wx.HORIZONTAL|wx.TB_FLAT|wx.TB_NODIVIDER)
self.toolBars[numToolBar].SetToolBitmapSize((16,16))
if toolBarItem == NID_TOOLBAR_HSEP:
self.toolBars[numToolBar].AddSeparator()
elif toolBarItem == NID_TOOLBAR_VSEP:
numToolBar += 1; self.toolBars.append(None);
elif toolBarItem[1] == TID_SELECT:
self.itemsById[toolBarItem[0]] = toolBarItem
toolBarItemWindow = \
self.toolBars[numToolBar].AddRadioTool( \
toolBarItem[0], toolBarItem[2], toolBarItem[4][2])
self.toolBarItemsById[toolBarItem[0]] = toolBarItemWindow
if toolBarItem[6] != None:
toolBarItemWindow.Toggle(toolBarItem[6])
self.Bind(wx.EVT_TOOL, self.onInput, toolBarItemWindow)
self.Bind(wx.EVT_TOOL_RCLICKED, self.onInput, toolBarItemWindow)
else:
self.itemsById[toolBarItem[0]] = toolBarItem
toolBarItemWindow = \
self.toolBars[numToolBar].AddTool( \
toolBarItem[0], toolBarItem[2], toolBarItem[4][2])
self.toolBarItemsById[toolBarItem[0]] = toolBarItemWindow
if toolBarItem[6] != None:
toolBarItemWindow.Enable(toolBarItem[6])
self.Bind(wx.EVT_TOOL, self.onInput, toolBarItemWindow)
self.Bind(wx.EVT_TOOL_RCLICKED, self.onInput, toolBarItemWindow)
for numToolBar in range(len(self.toolBars)):
self.sizerSkin.Add( \
self.toolBars[numToolBar], 0, wx.ALL|wx.ALIGN_LEFT, 3)
self.toolBars[numToolBar].Realize()
self.toolBars[numToolBar].Fit()
# }}}
# {{{ _initToolBitmaps(self, toolBarsDescr): XXX
def _initToolBitmaps(self, toolBarsDescr):
for toolBarItem in toolBarsDescr[2]:
if toolBarItem == NID_TOOLBAR_HSEP \
or toolBarItem == NID_TOOLBAR_VSEP:
continue
elif toolBarItem[4] == None:
toolBarItem[4] = ["", None, wx.ArtProvider.GetBitmap( \
wx.ART_HELP, wx.ART_TOOLBAR, (16,16))]
elif toolBarItem[4][0] == "" \
and toolBarItem[4][1] != None:
toolBarItem[4] = ["", None, wx.ArtProvider.GetBitmap( \
toolBarItem[4][1], wx.ART_TOOLBAR, (16,16))]
elif toolBarItem[4][0] == "" \
and toolBarItem[4][1] == None:
toolBarItem[4] = ["", None, toolBarItem[4][2]]
elif toolBarItem[4][0] != "":
toolBitmapPathName = os.path.dirname(sys.argv[0])
toolBitmapPathName = os.path.join(toolBitmapPathName, \
"assets", toolBarItem[4][0])
toolBitmap = wx.Bitmap((16,16))
toolBitmap.LoadFile(toolBitmapPathName, wx.BITMAP_TYPE_ANY)
toolBarItem[4] = ["", None, toolBitmap]
# }}}
# {{{ onInput(self, event): XXX
def onInput(self, event):
pass
# }}}
#
# __init__(self, *args, **kwargs): initialisation method
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs); self.itemsById = {};
panelSkin = wx.Panel(self, wx.ID_ANY)
# Initialise accelerators (hotkeys)
accelTable = wx.AcceleratorTable( \
self._initAccelTable(self.LID_ACCELS[2]))
self.SetAcceleratorTable(accelTable)
# Initialise menu bar, menus & menu items
# Initialise toolbar & toolbar items
menuBar = self._initMenus(self.LID_MENUS[2])
self.SetMenuBar(menuBar)
self._initToolBitmaps(self.LID_TOOLBARS[2])
toolBar = self._initToolBars(self.LID_TOOLBARS[2], panelSkin)
# Initialise status bar
self.statusBar = self.CreateStatusBar()
# Set focus on & show window
self.SetFocus(); self.Show(True);
return panelSkin
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,28 +0,0 @@
#!/usr/bin/env python3
#
# MiRCARTImgurApiKey.py -- melp?
# 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.
#
class MiRCARTImgurApiKey(object):
imgurApiKey = None
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,28 +0,0 @@
#!/bin/sh
#
# MiRCARTToPngFiles.sh -- convert ASCII(s) w/ mIRC control codes to monospaced PNG(s) (for EFnet #MiRCART)
# 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.
for FNAME in "${@}"; do
./MiRCARTToPngFile.py "${FNAME}" "${FNAME%.txt}.png";
done;
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,43 +0,0 @@
#!/usr/bin/env python3
#
# MiRCARTTool.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.
#
class MiRCARTTool():
"""XXX"""
parentCanvas = None
# {{{ onKeyboardEvent(self, event, atPoint, brushColours, brushSize, keyChar, dispatchFn, eventDc):
def onKeyboardEvent(self, event, atPoint, brushColours, brushSize, keyChar, dispatchFn, eventDc):
return True
# }}}
# {{{ onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): XXX
def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc):
return ()
# }}}
#
# __init__(self, parentCanvas): initialisation method
def __init__(self, parentCanvas):
self.parentCanvas = parentCanvas
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,56 +0,0 @@
#!/usr/bin/env python3
#
# MiRCARTToolCircle.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.
#
from MiRCARTTool import MiRCARTTool
class MiRCARTToolCircle(MiRCARTTool):
"""XXX"""
name = "Circle"
#
# onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): XXX
def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc):
brushColours = brushColours.copy()
if isLeftDown:
brushColours[1] = brushColours[0]
elif isRightDown:
brushColours[0] = brushColours[1]
else:
brushColours[1] = brushColours[0]
_brushSize = brushSize[0]*2
originPoint = (_brushSize/2, _brushSize/2)
radius = _brushSize
for brushY in range(-radius, radius + 1):
for brushX in range(-radius, radius + 1):
if ((brushX**2)+(brushY**2) < (((radius**2)+radius)*0.8)):
patch = [ \
atPoint[0] + int(originPoint[0]+brushX), \
atPoint[1] + int(originPoint[1]+brushY), \
*brushColours, 0, " "]
if isLeftDown or isRightDown:
dispatchFn(eventDc, False, patch); dispatchFn(eventDc, True, patch);
else:
dispatchFn(eventDc, True, patch)
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,56 +0,0 @@
#!/usr/bin/env python3
#
# MiRCARTToolFill.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.
#
from MiRCARTTool import MiRCARTTool
class MiRCARTToolFill(MiRCARTTool):
"""XXX"""
name = "Fill"
#
# onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): XXX
def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc):
pointStack = [list(atPoint)]; pointsDone = [];
testColour = self.parentCanvas.canvasMap[atPoint[1]][atPoint[0]][0:2]
if isLeftDown or isRightDown:
if isRightDown:
brushColours = [brushColours[1], brushColours[0]]
while len(pointStack) > 0:
point = pointStack.pop()
pointCell = self.parentCanvas.canvasMap[point[1]][point[0]]
if pointCell[0:2] == testColour:
if not point in pointsDone:
dispatchFn(eventDc, False, [*point, \
brushColours[0], brushColours[0], 0, " "])
if point[0] > 0:
pointStack.append([point[0] - 1, point[1]])
if point[0] < (self.parentCanvas.canvasSize[0] - 1):
pointStack.append([point[0] + 1, point[1]])
if point[1] > 0:
pointStack.append([point[0], point[1] - 1])
if point[1] < (self.parentCanvas.canvasSize[1] - 1):
pointStack.append([point[0], point[1] + 1])
pointsDone += [point]
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,105 +0,0 @@
#!/usr/bin/env python3
#
# MiRCARTToolLine.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.
#
from MiRCARTTool import MiRCARTTool
class MiRCARTToolLine(MiRCARTTool):
"""XXX"""
name = "Line"
toolColours = toolOriginPoint = toolState = None
TS_NONE = 0
TS_ORIGIN = 1
# {{{ _pointDelta(self, a, b): XXX
def _pointDelta(self, a, b):
return [a2-a1 for a1, a2 in zip(a, b)]
# }}}
# {{{ _pointSwap(self, a, b): XXX
def _pointSwap(self, a, b):
return [b, a]
# }}}
# {{{ _getLine(self, brushColours, brushSize, eventDc, isCursor, originPoint, targetPoint, dispatchFn): XXX
def _getLine(self, brushColours, brushSize, eventDc, isCursor, originPoint, targetPoint, dispatchFn):
originPoint = originPoint.copy(); targetPoint = targetPoint.copy();
pointDelta = self._pointDelta(originPoint, targetPoint)
lineXSign = 1 if pointDelta[0] > 0 else -1;
lineYSign = 1 if pointDelta[1] > 0 else -1;
pointDelta = [abs(a) for a in pointDelta]
if pointDelta[0] > pointDelta[1]:
lineXX, lineXY, lineYX, lineYY = lineXSign, 0, 0, lineYSign
else:
pointDelta = [pointDelta[1], pointDelta[0]]
lineXX, lineXY, lineYX, lineYY = 0, lineYSign, lineXSign, 0
lineD = 2 * pointDelta[1] - pointDelta[0]; lineY = 0;
for lineX in range(pointDelta[0] + 1):
for brushStep in range(brushSize[0]):
patch = [ \
originPoint[0] + lineX*lineXX + lineY*lineYX + brushStep, \
originPoint[1] + lineX*lineXY + lineY*lineYY, \
*brushColours, 0, " "]
if isCursor:
dispatchFn(eventDc, False, patch); dispatchFn(eventDc, True, patch);
else:
dispatchFn(eventDc, True, patch)
if lineD > 0:
lineD -= pointDelta[0]; lineY += 1;
lineD += pointDelta[1]
# }}}
#
# onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): XXX
def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc):
brushColours = brushColours.copy()
if isLeftDown:
brushColours[1] = brushColours[0]
elif isRightDown:
brushColours[0] = brushColours[1]
else:
brushColours[1] = brushColours[0]
if self.toolState == self.TS_NONE:
if isLeftDown or isRightDown:
self.toolColours = brushColours
self.toolOriginPoint = list(atPoint)
self.toolState = self.TS_ORIGIN
dispatchFn(eventDc, True, [*atPoint, *brushColours, 0, " "])
elif self.toolState == self.TS_ORIGIN:
targetPoint = list(atPoint)
originPoint = self.toolOriginPoint
self._getLine(self.toolColours, brushSize, \
eventDc, isLeftDown or isRightDown, \
originPoint, targetPoint, dispatchFn)
if isLeftDown or isRightDown:
self.toolColours = None
self.toolOriginPoint = None
self.toolState = self.TS_NONE
# __init__(self, *args): initialisation method
def __init__(self, *args):
super().__init__(*args)
self.toolColours = None
self.toolOriginPoint = None
self.toolState = self.TS_NONE
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,52 +0,0 @@
#!/usr/bin/env python3
#
# MiRCARTToolRect.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.
#
from MiRCARTTool import MiRCARTTool
class MiRCARTToolRect(MiRCARTTool):
"""XXX"""
name = "Rectangle"
#
# onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): XXX
def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc):
brushColours = brushColours.copy()
if isLeftDown:
brushColours[1] = brushColours[0]
elif isRightDown:
brushColours[0] = brushColours[1]
else:
brushColours[1] = brushColours[0]
brushSize = brushSize.copy()
if brushSize[0] > 1:
brushSize[0] *= 2
for brushRow in range(brushSize[1]):
for brushCol in range(brushSize[0]):
patch = [atPoint[0] + brushCol, atPoint[1] + brushRow, *brushColours, 0, " "]
if isLeftDown or isRightDown:
dispatchFn(eventDc, False, patch); dispatchFn(eventDc, True, patch);
else:
dispatchFn(eventDc, True, patch)
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,129 +0,0 @@
#!/usr/bin/env python3
#
# MiRCARTToolSelect.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.
#
from MiRCARTTool import MiRCARTTool
class MiRCARTToolSelect(MiRCARTTool):
"""XXX"""
toolColours = toolRect = toolState = None
toolLastAtPoint = None
toolSelectMap = None
srcRect = None
TS_NONE = 0
TS_ORIGIN = 1
TS_TARGET = 2
# {{{ _drawSelectRect(self, rect, dispatchFn, eventDc): XXX
def _drawSelectRect(self, rect, dispatchFn, eventDc):
rectFrame = [ \
[rect[0][0]-1, rect[0][1]-1], \
[rect[1][0]+1, rect[1][1]+1]]
if rectFrame[0][0] > rectFrame[1][0]:
rectFrame[0][0], rectFrame[1][0] = \
rectFrame[1][0], rectFrame[0][0]
if rectFrame[0][1] > rectFrame[1][1]:
rectFrame[0][1], rectFrame[1][1] = \
rectFrame[1][1], rectFrame[0][1]
curColours = [0, 0]
for rectX in range(rectFrame[0][0], rectFrame[1][0]+1):
if curColours == [0, 0]:
curColours = [1, 1]
else:
curColours = [0, 0]
dispatchFn(eventDc, True, \
[rectX, rectFrame[0][1], *curColours, 0, " "])
dispatchFn(eventDc, True, \
[rectX, rectFrame[1][1], *curColours, 0, " "])
for rectY in range(rectFrame[0][1], rectFrame[1][1]+1):
if curColours == [0, 0]:
curColours = [1, 1]
else:
curColours = [0, 0]
dispatchFn(eventDc, True, \
[rectFrame[0][0], rectY, *curColours, 0, " "])
dispatchFn(eventDc, True, \
[rectFrame[1][0], rectY, *curColours, 0, " "])
# }}}
#
# onSelectEvent(self, event, atPoint, selectRect, brushColours, brushSize, isLeftDown, isRightDown, dispatchFn, eventDc): XXX
def onSelectEvent(self, event, atPoint, selectRect, brushColours, brushSize, isLeftDown, isRightDown, dispatchFn, eventDc):
pass
#
# onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): XXX
def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc):
if self.toolState == self.TS_NONE:
if isLeftDown or isRightDown:
self.toolColours = [0, 1]
self.toolRect = [list(atPoint), []]
self.toolState = self.TS_ORIGIN
else:
dispatchFn(eventDc, True, \
[*atPoint, *brushColours, 0, " "])
elif self.toolState == self.TS_ORIGIN:
self.toolRect[1] = list(atPoint)
if isLeftDown or isRightDown:
if self.toolRect[0][0] > self.toolRect[1][0]:
self.toolRect[0][0], self.toolRect[1][0] = \
self.toolRect[1][0], self.toolRect[0][0]
if self.toolRect[0][1] > self.toolRect[1][1]:
self.toolRect[0][1], self.toolRect[1][1] = \
self.toolRect[1][1], self.toolRect[0][1]
self.srcRect = self.toolRect[0]
self.toolLastAtPoint = list(atPoint)
self.toolState = self.TS_TARGET
self.toolSelectMap = []
for numRow in range((self.toolRect[1][1] - self.toolRect[0][1]) + 1):
self.toolSelectMap.append([])
for numCol in range((self.toolRect[1][0] - self.toolRect[0][0]) + 1):
rectY = self.toolRect[0][1] + numRow
rectX = self.toolRect[0][0] + numCol
self.toolSelectMap[numRow].append( \
self.parentCanvas.canvasMap[rectY][rectX])
self._drawSelectRect(self.toolRect, dispatchFn, eventDc)
elif self.toolState == self.TS_TARGET:
if isRightDown:
self.onSelectEvent(event, atPoint, self.toolRect, \
brushColours, brushSize, isLeftDown, isRightDown, \
dispatchFn, eventDc)
self.toolColours = None
self.toolRect = None
self.toolState = self.TS_NONE
else:
self.onSelectEvent(event, atPoint, self.toolRect, \
brushColours, brushSize, isLeftDown, isRightDown, \
dispatchFn, eventDc)
# __init__(self, *args): initialisation method
def __init__(self, *args):
super().__init__(*args)
self.toolColours = None
self.toolRect = None
self.toolState = self.TS_NONE
self.toolLastAtPoint = None
self.toolSelectMap = None
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,60 +0,0 @@
#!/usr/bin/env python3
#
# MiRCARTToolSelectClone.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.
#
from MiRCARTToolSelect import MiRCARTToolSelect
class MiRCARTToolSelectClone(MiRCARTToolSelect):
"""XXX"""
name = "Clone selection"
#
# onSelectEvent(self, event, atPoint, selectRect, brushColours, brushSize, isLeftDown, isRightDown, dispatchFn, eventDc): XXX
def onSelectEvent(self, event, atPoint, selectRect, brushColours, brushSize, isLeftDown, isRightDown, dispatchFn, eventDc):
if isLeftDown:
atPoint = list(atPoint)
disp = [atPoint[0]-self.toolLastAtPoint[0], \
atPoint[1]-self.toolLastAtPoint[1]]
self.toolLastAtPoint = atPoint
newToolRect = [ \
[selectRect[0][0]+disp[0], selectRect[0][1]+disp[1]], \
[selectRect[1][0]+disp[0], selectRect[1][1]+disp[1]]]
isCursor = True
elif isRightDown:
disp = [0, 0]
newToolRect = selectRect.copy()
isCursor = False
else:
disp = [0, 0]
newToolRect = selectRect.copy()
isCursor = True
for numRow in range(len(self.toolSelectMap)):
for numCol in range(len(self.toolSelectMap[numRow])):
cellOld = self.toolSelectMap[numRow][numCol]
rectY = selectRect[0][1] + numRow
rectX = selectRect[0][0] + numCol
dispatchFn(eventDc, isCursor, [rectX+disp[0], rectY+disp[1], *cellOld])
self._drawSelectRect(newToolRect, dispatchFn, eventDc)
self.toolRect = newToolRect
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,64 +0,0 @@
#!/usr/bin/env python3
#
# MiRCARTToolSelectMove.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.
#
from MiRCARTToolSelect import MiRCARTToolSelect
class MiRCARTToolSelectMove(MiRCARTToolSelect):
"""XXX"""
name = "Move selection"
#
# onSelectEvent(self, event, atPoint, selectRect, brushColours, brushSize, isLeftDown, isRightDown, dispatchFn, eventDc): XXX
def onSelectEvent(self, event, atPoint, selectRect, brushColours, brushSize, isLeftDown, isRightDown, dispatchFn, eventDc):
if isLeftDown:
atPoint = list(atPoint)
disp = [atPoint[0]-self.toolLastAtPoint[0], \
atPoint[1]-self.toolLastAtPoint[1]]
self.toolLastAtPoint = atPoint
newToolRect = [ \
[selectRect[0][0]+disp[0], selectRect[0][1]+disp[1]], \
[selectRect[1][0]+disp[0], selectRect[1][1]+disp[1]]]
isCursor = True
elif isRightDown:
disp = [0, 0]
newToolRect = selectRect.copy()
isCursor = False
else:
disp = [0, 0]
newToolRect = selectRect.copy()
isCursor = True
for numRow in range(len(self.toolSelectMap)):
for numCol in range(len(self.toolSelectMap[numRow])):
dispatchFn(eventDc, isCursor, [self.srcRect[0] + numCol, \
self.srcRect[1] + numRow, 1, 1, 0, " "])
for numRow in range(len(self.toolSelectMap)):
for numCol in range(len(self.toolSelectMap[numRow])):
cellOld = self.toolSelectMap[numRow][numCol]
rectY = selectRect[0][1] + numRow
rectX = selectRect[0][0] + numCol
dispatchFn(eventDc, isCursor, [rectX+disp[0], rectY+disp[1], *cellOld])
self._drawSelectRect(newToolRect, dispatchFn, eventDc)
self.toolRect = newToolRect
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,70 +0,0 @@
#!/usr/bin/env python3
#
# MiRCARTToolText.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.
#
from MiRCARTTool import MiRCARTTool
import wx
class MiRCARTToolText(MiRCARTTool):
"""XXX"""
name = "Text"
textColours = textPos = None
#
# onKeyboardEvent(self, event, atPoint, brushColours, brushSize, keyChar, dispatchFn, eventDc): XXX
def onKeyboardEvent(self, event, atPoint, brushColours, brushSize, keyChar, dispatchFn, eventDc):
keyModifiers = event.GetModifiers()
if keyModifiers != wx.MOD_NONE \
and keyModifiers != wx.MOD_SHIFT:
return True
else:
if self.textColours == None:
self.textColours = brushColours.copy()
if self.textPos == None:
self.textPos = list(atPoint)
dispatchFn(eventDc, False, [*self.textPos, *self.textColours, 0, keyChar])
if self.textPos[0] < (self.parentCanvas.canvasSize[0] - 1):
self.textPos[0] += 1
elif self.textPos[1] < (self.parentCanvas.canvasSize[1] - 1):
self.textPos[0] = 0
self.textPos[1] += 1
else:
self.textPos = [0, 0]
return False
#
# onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): XXX
def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc):
if isLeftDown:
self.textColours = brushColours.copy()
self.textPos = list(atPoint)
elif isRightDown:
self.textColours = [brushColours[1], brushColours[0]]
self.textPos = list(atPoint)
else:
if self.textColours == None:
self.textColours = brushColours.copy()
self.textPos = list(atPoint)
dispatchFn(eventDc, True, [*self.textPos, *self.textColours, 0, "_"])
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,17 +0,0 @@
# MiRCART.py -- mIRC art editor for Windows & Linux (WIP)
* 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")
# IrcMiRCARTBot.py -- IRC<->MiRC2png bot (for EFnet #MiRCART) (pending cleanup)
* Prerequisites: python3 && python3-{json,requests,urllib3} on Debian-family Linux distributions
* IrcMiRCARTBot.py usage: IrcMiRCARTBot.py `<IRC server hostname>` [`<IRC server port; defaults to 6667>`] [`<IRC bot nick name; defaults to pngbot>`] [`<IRC bot user name; defaults to pngbot>`] [`<IRC bot real name; defaults to pngbot>`] [`<IRC bot channel name; defaults to #MiRCART>`]
# MiRCARTToPngFile.py -- convert ASCII w/ mIRC control codes to monospaced PNG (pending cleanup)
* Prerequisites: python3 && python3-pil on Debian-family Linux distributions
* MiRC2png.py usage: MiRC2png.py `<MiRCART input file pathname>` `<PNG image output file pathname>` [`<Font file pathname; defaults to DejaVuSansMono.ttf>`] [`<Font size; defaults to 11>`]
References:
Fri, 05 Jan 2018 17:01:47 +0100 [1] Python Releases for Windows | Python.org <https://www.python.org/downloads/windows/>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 360 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 277 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 250 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 265 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 289 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 249 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 527 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 236 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 236 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 371 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 213 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 306 B

1
README.md Symbolic link
View File

@ -0,0 +1 @@
assets/text/README.md

View File

@ -2,24 +2,7 @@
#
# mirc2png -- convert ASCII w/ mIRC control codes to monospaced PNG (for EFnet #MiRCART)
# 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.
# This project is licensed under the terms of the MIT licence.
#
from itertools import chain

View File

@ -2,24 +2,7 @@
#
# IrcMiRCARTBot.py -- IRC<->MiRC2png bot (for EFnet #MiRCART)
# 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.
# This project is licensed under the terms of the MIT licence.
#
from getopt import getopt, GetoptError

0
ENNTool/LICENCE → asciiblaster-python/LICENCE Normal file → Executable file
View File

View File

@ -2,24 +2,7 @@
#
# MiRCARTCanonicalise.py -- canonicalise mIRC art {from,to} file (for munki)
# 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.
# This project is licensed under the terms of the MIT licence.
#
from MiRCARTCanvasImportStore import MiRCARTCanvasImportStore

View File

@ -2,24 +2,7 @@
#
# MiRCARTCanvasImportStore.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.
# This project is licensed under the terms of the MIT licence.
#
class MiRCARTCanvasImportStore():

View File

@ -0,0 +1,17 @@
#!/bin/sh
#
# MiRCARTCheckLineLengths.py -- check mIRC art line lengths
# Copyright (c) 2018 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
# This project is licensed under the terms of the MIT licence.
#
for FNAME in "${@}"; do
FNAME_LINES="$(wc -l "${FNAME}" | awk '{print $1}')";
for FNAME_LINE in $(seq "${FNAME_LINES}"); do
printf "%-5d %-5d %s\n" \
"$(sed -n "${FNAME_LINE}p" "${FNAME}" | wc -c)" \
"${FNAME_LINE}" "${FNAME}";
done;
done | sort -nk1;
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -0,0 +1,11 @@
#!/usr/bin/env python3
#
# MiRCARTImgurApiKey.py -- melp?
# Copyright (c) 2018 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
# This project is licensed under the terms of the MIT licence.
#
class MiRCARTImgurApiKey(object):
imgurApiKey = None
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -2,24 +2,7 @@
#
# MiRCARTToPngFile.py -- convert ASCII w/ mIRC control codes to monospaced PNG (for EFnet #MiRCART)
# 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.
# This project is licensed under the terms of the MIT licence.
#
import MiRCARTCanvasImportStore

View File

@ -0,0 +1,12 @@
#!/bin/sh
#
# MiRCARTToPngFiles.sh -- convert ASCII(s) w/ mIRC control codes to monospaced PNG(s) (for EFnet #MiRCART)
# Copyright (c) 2018 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
# This project is licensed under the terms of the MIT licence.
#
for FNAME in "${@}"; do
./MiRCARTToPngFile.py "${FNAME}" "${FNAME%.txt}.png";
done;
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

15
assets/text/README.md Normal file
View File

@ -0,0 +1,15 @@
## MiRCART-{cordoba,nw,www} -- mIRC art editor for {Android,{Linux,Windows},browsers} (WIP)
Originally based on [[1](#r1)].
## IrcMiRCARTBot.py -- IRC<->MiRC2png bot (for EFnet #MiRCART) (pending cleanup)
* Prerequisites: python3 && python3-{json,requests,urllib3} on Debian-family Linux distributions
* IrcMiRCARTBot.py usage: IrcMiRCARTBot.py `<IRC server hostname>` [`<IRC server port; defaults to 6667>`] [`<IRC bot nick name; defaults to pngbot>`] [`<IRC bot user name; defaults to pngbot>`] [`<IRC bot real name; defaults to pngbot>`] [`<IRC bot channel name; defaults to #MiRCART>`]
## MiRCARTToPngFile.py -- convert ASCII w/ mIRC control codes to monospaced PNG (pending cleanup)
* Prerequisites: python3 && python3-pil on Debian-family Linux distributions
* MiRC2png.py usage: MiRC2png.py `<MiRCART input file pathname>` `<PNG image output file pathname>` [`<Font file pathname; defaults to DejaVuSansMono.ttf>`] [`<Font size; defaults to 11>`]
## References
``Fri, 05 Jan 2018 17:01:47 +0100 [1]`` <a href="https://asdf.us/asciiblaster" id="r1">asciiblaster</a>
vim:tw=0

2
mawj/.gitignore vendored
View File

@ -1,2 +0,0 @@
__pycache__/
*.sw[op]

View File

@ -1,19 +0,0 @@
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.

View File

@ -1,31 +0,0 @@
```
.. ░▒▓▓▓▓▓▓▓▓▓▒░ ░▒▓▓▓▒░ ░▒▓▓▓▒░ ..
/oo\ ▒░ ░▒ ▒░ ░▒ ▒░ /oo\
\oo/ ░▒▓▓▓▓▓▓▓▓▓▒░ ░▒▓▓▓▓▓▓▓▓▓▓▓▓▓▒░ \oo/
.. ░▒ ▒░ MiRCART ..
░▒ ░▒▓▓▓▓▓▒░ ░▒▓▓▓▒░ Animation
.. ░▒ ▒░ ..
/oo\ ░▒▓▓▓▓▓▓▓▓▓▒░__ __ _ /oo\
\oo/ via Waves | \/ |__ ___ __ _(_)\oo/
.. Generator | |\/| / _` \ V V / | ..
|_| |_\__,_|\_/\_// |
.. |__/ ..
/oo\ وَمُرْهَفٍ سرْتُ بينَ الجَحْفَلَينِ بهِ /oo\
\oo/ حتى ضرَبْتُ وَمَوْجُ المَوْتِ يَلْتَطِمُ \oo/
·· ··
```
# Mawj - **M**iRCART **A**nimation via **W**aves **G**enerator (WORK IN PROGRESS)
Copyright (c) 2018 Lucio Andrés Illanes Albornoz <<lucio@lucioillanes.de>>
This project is licensed under the terms of the MIT licence.
* Prerequisites on Linux: python3 && python-wx{gtk2.8,tools} && python3-opengl on Debian-family Linux distributions
* Prerequisites on Windows: install Python v3.5.x and script dependencies w/ the following elevated command prompt command line:
`pip install PyOpenGL wxPython`
### How to run:
```
usage: ./mawj.py -i <commands file>
```
### Commands file format:
TODO

View File

@ -1,334 +0,0 @@
#!/usr/bin/env python3
#
# mawj.py -- MiRCART Animation via Waves Generator
# Copyright (c) 2018 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
# This project is licensed under the terms of the MIT license.
#
from OpenGL.GL import *
from PIL import Image
import cv2, math, numpy, os, sys, wx, wx.glcanvas
MiRCARTColours = [
# {{{ MiRCARTColours: mIRC colour number to RGBA map given none of ^[BFV_] (bold, italic, reverse, underline],
[1.00, 1.00, 1.00], # White
[0.00, 0.00, 0.00], # Black
[0.00, 0.00, 0.73], # Blue
[0.00, 0.73, 0.00], # Green
[1.00, 0.33, 0.33], # Light Red
[0.73, 0.00, 0.00], # Red
[0.73, 0.00, 0.73], # Purple
[0.73, 0.73, 0.00], # Yellow
[1.00, 1.00, 0.33], # Light Yellow
[0.33, 1.00, 0.33], # Light Green
[0.00, 0.73, 0.73], # Cyan
[0.33, 1.00, 1.00], # Light Cyan
[0.33, 0.33, 1.00], # Light Blue
[1.00, 0.33, 1.00], # Pink
[0.33, 0.33, 0.33], # Grey
[0.73, 0.73, 0.73], # Light Grey
]
# }}}
class MawjMiRCARTImporter(object):
"""XXX"""
# {{{ _CellState(): Cell state
class _CellState():
CS_NONE = 0x00
CS_BOLD = 0x01
CS_ITALIC = 0x02
CS_UNDERLINE = 0x04
# }}}
# {{{ _ParseState(): Parsing loop state
class _ParseState():
PS_CHAR = 1
PS_COLOUR_DIGIT0 = 2
PS_COLOUR_DIGIT1 = 3
# }}}
# {{{ _flipCellStateBit(self, cellState, bit): XXX
def _flipCellStateBit(self, cellState, bit):
if cellState & bit:
return cellState & ~bit
else:
return cellState | bit
# }}}
# {{{ _parseCharAsColourSpec(self, colourSpec, curColours): XXX
def _parseCharAsColourSpec(self, colourSpec, curColours):
if len(colourSpec) > 0:
colourSpec = colourSpec.split(",")
if len(colourSpec) == 2 \
and len(colourSpec[1]) > 0:
return [int(colourSpec[0] or curColours[0]), \
int(colourSpec[1])]
elif len(colourSpec) == 1 \
or len(colourSpec[1]) == 0:
return [int(colourSpec[0]), curColours[1]]
else:
return [15, 1]
# }}}
# {{{ fromTextFile(self, pathName): XXX
def fromTextFile(self, pathName):
self.inFile = open(pathName, "r")
self.inSize = self.outMap = None;
inCurColourSpec = ""; inCurRow = -1;
inLine = self.inFile.readline()
inSize = [0, 0]; outMap = []; inMaxCols = 0;
while inLine:
inCellState = self._CellState.CS_NONE
inParseState = self._ParseState.PS_CHAR
inCurCol = 0; inMaxCol = len(inLine);
inCurColourDigits = 0; inCurColours = [15, 1]; inCurColourSpec = "";
inCurRow += 1; outMap.append([]); inRowCols = 0; inSize[1] += 1;
while inCurCol < inMaxCol:
inChar = inLine[inCurCol]
if inChar in set("\r\n"): \
inCurCol += 1
elif inParseState == self._ParseState.PS_CHAR:
inCurCol += 1
if inChar == "":
inCellState = self._flipCellStateBit( \
inCellState, self._CellState.CS_BOLD)
elif inChar == "":
inParseState = self._ParseState.PS_COLOUR_DIGIT0
elif inChar == "":
inCellState = self._flipCellStateBit( \
inCellState, self._CellState.CS_ITALIC)
elif inChar == "":
inCellState |= self._CellState.CS_NONE
inCurColours = [15, 1]
elif inChar == "":
inCurColours = [inCurColours[1], inCurColours[0]]
elif inChar == "":
inCellState = self._flipCellStateBit( \
inCellState, self._CellState.CS_UNDERLINE)
else:
inRowCols += 1
outMap[inCurRow].append([*inCurColours, inCellState, inChar])
elif inParseState == self._ParseState.PS_COLOUR_DIGIT0 \
or inParseState == self._ParseState.PS_COLOUR_DIGIT1:
if inChar == "," \
and inParseState == self._ParseState.PS_COLOUR_DIGIT0:
if (inCurCol + 1) < inMaxCol \
and not inLine[inCurCol + 1] in set("0123456789"):
inCurColours = self._parseCharAsColourSpec( \
inCurColourSpec, inCurColours)
inCurColourDigits = 0; inCurColourSpec = "";
inParseState = self._ParseState.PS_CHAR
else:
inCurCol += 1
inCurColourDigits = 0; inCurColourSpec += inChar;
inParseState = self._ParseState.PS_COLOUR_DIGIT1
elif inChar in set("0123456789") \
and inCurColourDigits == 0:
inCurCol += 1
inCurColourDigits += 1; inCurColourSpec += inChar;
elif inChar in set("0123456789") \
and inCurColourDigits == 1 \
and inCurColourSpec[-1] == "0":
inCurCol += 1
inCurColourDigits += 1; inCurColourSpec += inChar;
elif inChar in set("012345") \
and inCurColourDigits == 1 \
and inCurColourSpec[-1] == "1":
inCurCol += 1
inCurColourDigits += 1; inCurColourSpec += inChar;
else:
inCurColours = self._parseCharAsColourSpec( \
inCurColourSpec, inCurColours)
inCurColourDigits = 0; inCurColourSpec = "";
inParseState = self._ParseState.PS_CHAR
inMaxCols = max(inMaxCols, inRowCols)
inLine = self.inFile.readline()
inSize[0] = inMaxCols; self.inSize = inSize; self.outMap = outMap;
self.inFile.close()
# }}}
# {{{ __init__(self, inFile): initialisation method
def __init__(self, inFile):
self.inFile = inFile; self.inSize = self.outMap = None;
self.fromTextFile(inFile)
# }}}
class MawjFrame(wx.Frame):
"""XXX"""
# {{{ __init__(self, parent, size, videoPath=None): initialisation method
def __init__(self, parent, size, videoPath=None):
super().__init__(parent, size=size)
self.panelSkin = wx.Panel(self, wx.ID_ANY)
self.panelGLCanvas = MawjGLCanvasPanel(self.panelSkin, size=[s-128 for s in size], videoPath=videoPath)
self.Bind(wx.EVT_MOUSEWHEEL, self.panelGLCanvas.onMouseWheel)
self.SetFocus(); self.Show(True);
# }}}
class MawjGLCanvasPanel(wx.glcanvas.GLCanvas, wx.Panel):
"""XXX"""
# {{{ drawAll(self, deltaX=0, deltaY=0, deltaZ=0, paintFlag=False): XXX
def drawAll(self, deltaX=0, deltaY=0, deltaZ=0, paintFlag=False):
self.SetCurrent(self.glContext)
if not self.hasGLInit:
self.onGLInit(); self.hasGLInit = True;
if deltaX != 0 or deltaY != 0 or deltaZ != 0 or paintFlag:
self.isDirty = True
if self.isDirty:
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
glBegin(GL_QUADS)
curPos = [0,0,0]; cubeSize = (0.1,0.2);
for numRow in range(len(self.MiRCART.outMap)):
for numCol in range(len(self.MiRCART.outMap[numRow])):
cubeColour = MiRCARTColours[self.MiRCART.outMap[numRow][numCol][1]]
self.drawIrcCube(colour=cubeColour, pos=curPos, size=cubeSize)
curPos[0] += cubeSize[0]
curPos[0] = 0; curPos[1] -= cubeSize[1];
glEnd()
if deltaX != 0 or deltaY != 0:
w, h = self.GetClientSize(); w = max(w, 1.0); h = max(h, 1.0);
glRotatef(deltaY * (180.0/h), 1.0, 0.0, 0.0)
glRotatef(deltaX * (180.0/w), 0.0, 1.0, 0.0)
if deltaZ != 0:
glTranslatef(0, 0, deltaZ)
self.isDirty = False; self.SwapBuffers(); self.snap();
# }}}
# {{{ drawIrcCube(self, colour=(1.0, 0.0, 0.0), pos=(0,0,0), size=(0.1,0.2)): XXX
def drawIrcCube(self, colour=(1.0, 0.0, 0.0), pos=(0,0,0), size=(0.1,0.2)):
# Top Right, Top Left, Bottom Left, Bottom Right
glColor3f(*colour)
glNormal3f(0.0, 0.0, 1.0)
glVertex3f(pos[0], pos[1], pos[2])
glVertex3f(pos[0]-size[0], pos[1], pos[2])
glVertex3f(pos[0]-size[0], pos[1]-size[1], pos[2])
glVertex3f(pos[0], pos[1]-size[1], pos[2])
# }}}
# {{{ onGLInit(self): XXX
def onGLInit(self):
# <https://www.opengl.org/discussion_boards/showthread.php/125843-default-camera?p=954801&viewfull=1#post954801>
glViewport(0, 0, *self.curSize)
glMatrixMode(GL_PROJECTION)
glLoadIdentity(); glFrustum(-1, 1, -1, 1, 1, 100);
glMatrixMode(GL_MODELVIEW)
glEnable(GL_DEPTH_TEST)
glClearColor(0, 0, 0, 1); glClearDepth(1);
glTranslatef(-5.0, 3.0, -5)
# <https://www.khronos.org/opengl/wiki/How_lighting_works#Good_Settings.>
glLight(GL_LIGHT0, GL_AMBIENT, (0, 0, 0, 1))
glLight(GL_LIGHT0, GL_DIFFUSE, (1, 1, 1, 1))
glLight(GL_LIGHT0, GL_POSITION, (1, 1, 0+2, 0))
glLight(GL_LIGHT0, GL_SPECULAR, (1, 1, 1, 1))
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (0.2, 0.2, 0.2, 1))
glEnable(GL_LIGHTING); glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL)
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)
if self.videoPath != None:
width, height = self.GetClientSize()
fourcc = cv2.VideoWriter_fourcc("X", "V", "I", "D")
self.videoWriter = cv2.VideoWriter(self.videoPath, fourcc, 25, (width, height), True)
# }}}
# {{{ onMouseDown(self, event): XXX
def onMouseDown(self, event):
self.CaptureMouse(); self.mouseXlast, self.mouseYlast = event.GetPosition();
# }}}
# {{{ onMouseMotion(self, event): XXX
def onMouseMotion(self, event):
if event.Dragging():
if event.LeftIsDown():
mouseX, mouseY = event.GetPosition()
self.drawAll(deltaX=mouseX-self.mouseXlast, deltaY=mouseY-self.mouseYlast)
self.mouseXlast, self.mouseYlast = mouseX, mouseY
elif event.RightIsDown():
mouseX, mouseY = event.GetPosition()
self.swirlAll(2, 30.0)
self.drawAll(paintFlag=True)
self.mouseXlast, self.mouseYlast = mouseX, mouseY
# }}}
# {{{ onMouseWheel(self, event): XXX
def onMouseWheel(self, event):
wheelRotation = event.GetWheelRotation()
if wheelRotation < 0:
self.drawAll(deltaZ=-1)
else:
self.drawAll(deltaZ=1)
# }}}
# {{{ onMouseUp(self, event): XXX
def onMouseUp(self, event):
self.ReleaseMouse(); self.mouseXlast = self.mouseYlast = 0;
# }}}
# {{{ onPaint(self, event): XXX
def onPaint(self, event):
eventDc = wx.PaintDC(self)
eventUpdates = wx.RegionIterator(self.GetUpdateRegion())
paintFlag = True if eventUpdates.HaveRects() else False
self.drawAll(paintFlag=paintFlag)
# }}}
# {{{ snap(self): XXX
def snap(self):
width, height = self.GetClientSize()
if sys.byteorder == "little":
screenshot = glReadPixels(0, 0, width, height, GL_BGR, GL_UNSIGNED_BYTE)
else:
screenshot = glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE)
screenshot = numpy.flipud(numpy.frombuffer(screenshot, numpy.uint8).reshape((height, width, 3)))
self.videoWriter.write(screenshot)
# }}}
# {{{ swirlAll(self, radiusDiv=4, step=30.0): XXX
def swirlAll(self, radiusDiv=4, step=30.0):
# <http://geekofficedog.blogspot.de/2013/04/hello-swirl-swirl-effect-tutorial-in.html>
width = len(self.MiRCART.outMap[0]); height = len(self.MiRCART.outMap);
centerX = math.floor(width / 2); centerY = math.floor(height / 2);
size = width if width < height else height
radius = math.floor(size / radiusDiv)
newMap = self.MiRCART.outMap.copy()
for y in range(-radius, radius):
for x in range(-radius, radius):
# Transform the pixel cartesian coordinates (x, y) to polar coordinates (r, alpha)
# Remember that the angle alpha is in radians, transform it to degrees
r = math.sqrt(pow(x, 2) + pow(y, 2)); alpha = math.atan2(y, x);
degrees = (alpha * 180.0) / math.pi
# Shift the angle by a constant delta
# Note the '-' sign was changed by '+' the inverted function
degrees -= step
# Transform back from polar coordinates to cartesian
alpha = (degrees * math.pi) / 180.0
newY = math.floor(r * math.sin(alpha)); newX = math.floor(r * math.cos(alpha));
try:
# Calculate the pixel array position
# Get the new pixel location
srcPosY = y + centerY; srcPosX = x + centerX;
destPosY = newY + centerY; destPosX = newX + centerX;
newMap[destPosY][destPosX] = self.MiRCART.outMap[srcPosY][srcPosX]
except IndexError:
continue
self.MiRCART.outMap = newMap
# }}}
# {{{ __init__(self, parent, size, defaultPos=(24,24), videoPath=None): initialisation method
def __init__(self, parent, size, defaultPos=(24,24), videoPath=None):
super().__init__(parent, pos=defaultPos, size=size)
self.curPos = list(defaultPos); self.curSize = list(size);
self.glContext = wx.glcanvas.GLContext(self);
self.hasGLInit = False; self.isDirty = True;
self.mouseXlast = self.mouseYlast = 0;
self.Bind(wx.EVT_LEFT_DOWN, self.onMouseDown)
self.Bind(wx.EVT_LEFT_UP, self.onMouseUp)
self.Bind(wx.EVT_MOTION, self.onMouseMotion)
self.Bind(wx.EVT_PAINT, self.onPaint)
self.MiRCART = MawjMiRCARTImporter("puke.txt"); self.videoPath = videoPath;
# }}}
#
# Entry point
def main(*argv):
wxApp = wx.App(False)
appFrame = MawjFrame(None, size=(1152,864), videoPath=os.path.join("F:\\", "mawj.avi"))
wxApp.MainLoop()
if __name__ == "__main__":
main(*sys.argv)
# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120

View File

@ -1,36 +0,0 @@
0,1 3,3 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 3,3 0,1 0,0 1,1 0,1 0,0 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 1,1 9,9 1,1 9,9 1,1 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1
3,3 0,1 3,3 0,1 9,9 0,1 9,9 1,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 0,0 0,1 0,0 0,1 0,0 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1 1,1 9,9 0,1 9,9 1,1 0,1 9,9 0,1 9,9 0,1 9,9 0,1 9,9 0,1
0,1 3,3 0,1 9,9 0,1 11,11 10,10 11,11 0,1 9,9 0,1 9,9 0,1 3,3 0,1 3,3 0,1 0,0 0,1 0,0 0,1 0,0 0,1 9,9 0,1 9,9 0,1 9,9 0,1 1,1 9,9 0,1 1,1 0,1 9,9 0,1 9,9 0,1
0,1 3,3 0,1 3,3 0,1 10,10 11,11 10,10 11,11 10,10 0,1 3,3 0,1 3,3 0,1 0,0 0,1 3,3 0,1 3,3 0,1 1,1 3,3 1,1 3,3 1,1 9,9 1,1 9,9 1,1 3,3 1,1 3,3 1,1 0,1 3,3 0,1 3,3 0,1
9,9 1,1 3,3 1,1 10,10 11,11 10,10 11,11 10,10 1,1 0,0 1,1 11,11 1,10 1,1 11,11 1,1 3,3 1,1 9,9 1,1 3,3 1,1 11,11 1,1 1,10 11,11 0,1 9,9
9,9 1,1 10,10 11,11 10,10 11,11 10,10 11,11 1,1 3,3 1,1 11,11 1,10 1,1 11,11 1,1 3,3 1,1 3,3 1,1 11,11 1,1 1,10 11,11 0,1 9,9
9,9 1,1 10,10 11,11 10,10 11,11 10,10 1,1 8,8 1,1 11,11 1,10 1,1 11,11 1,1 3,3 1,1 11,11 1,1 1,10 11,11 1,1 0,1 9,9
9,9 1,1 11,11 10,10 11,11 10,10 11,11 10,10 11,11 10,10 1,1 8,8 1,1 8,8 1,1 11,11 1,10 1,1 11,11 1,1 1,10 11,11 1,1 0,1 9,9
9,9 1,1 11,11 10,10 11,11 10,10 11,10 10,10 11,11 10,10 1,1 8,8 1,1 8,8 1,1 11,11 1,10 1,1 1,10 11,11 1,1 0,1 9,9
9,9 1,1 11,11 10,10 11,11 10,10 11,11 10,10 1,1 8,8 1,1 8,8 1,1 8,8 1,1 0,0 1,1 8,8 1,1 8,8 1,1 8,8 1,1 11,11 1,10 11,11 1,10 11,11 1,1 0,1 9,9
1,3 9,9 1,1 11,11 10,10 11,11 10,10 11,11 1,1 8,8 1,1 8,8 1,1 8,8 1,1 0,0 1,1 0,0 1,1 8,8 1,1 8,8 1,1 8,8 1,1 11,11 10,10 11,11 1,1 0,1 9,9 1,3
3,3 9,9 1,1 3,3 1,1 3,3 1,1 11,11 10,10 1,1 8,8 1,1 8,8 1,1 8,8 1,1 0,0 1,1 8,8 1,1 8,8 1,1 8,8 1,1 3,3 9,9 3,3 1,1 0,1 9,9 1,3
3,3 9,9 1,1 3,3 1,1 3,3 1,1 3,3 1,1 3,3 1,1 8,8 1,1 8,8 1,1 8,8 1,1 0,0 1,1 8,8 1,1 8,8 1,1 0,0 1,1 8,8 1,1 8,8 1,1 8,8 1,1 3,3 9,9 1,1 0,1 9,9 1,3
3,3 9,9 1,1 3,3 1,1 3,3 1,1 3,3 1,1 3,3 1,1 8,8 1,1 8,8 1,1 8,8 1,1 0,0 1,1 0,0 1,1 8,8 1,1 8,8 1,1 0,0 1,1 0,0 1,1 8,8 1,1 8,8 1,1 8,8 1,1 3,3 9,9 3,3 1,1 0,1 9,9 1,3
3,3 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 7,7 8,8 1,1 8,8 1,1 8,8 1,1 0,0 1,1 8,8 1,1 0,0 1,1 8,8 1,1 8,8 1,1 8,8 1,1 9,9 3,3 1,1 0,1 9,9 1,3
1,3 3,3 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 7,7 8,8 1,1 8,8 1,1 8,8 1,1 3,3 9,9 3,3 1,1 0,1 9,9 1,3
11,11 3,3 9,9 1,1 7,7 8,8 1,1 8,8 1,1 8,8 1,1 8,8 1,1 3,3 9,9 1,1 0,1 9,9 1,3 11,11
11,11 3,3 9,9 1,1 3,3 1,1 3,3 1,1 3,3 1,1 3,3 1,1 3,3 1,1 3,3 1,1 7,7 8,8 1,1 0,0 1,1 8,8 1,1 3,3 9,9 3,3 1,1 0,1 9,9 1,3 11,11
11,11 1,3 3,3 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 7,7 8,8 1,1 8,8 1,1 9,9 3,3 1,1 0,1 9,9 1,3 11,11
10,10 3,11 1,3 3,3 9,9 1,1 3,3 1,1 3,3 1,1 7,7 8,8 1,1 0,0 1,1 0,0 1,1 0,0 1,1 8,8 1,1 3,3 1,1 9,9 1,3 3,11 10,10
10,10 3,11 1,3 3,3 9,9 1,1 3,3 1,1 3,3 1,1 3,3 1,1 3,3 1,1 3,3 1,1 7,7 8,8 8,1 1,1 8,1 8,8 1,1 9,9 3,3 1,1 9,9 1,3 3,11 10,10
10,10 3,11 1,3 3,3 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 9,9 1,1 7,7 8,8 8,1 0,0 1,1 0,0 1,1 0,0 8,1 8,8 1,1 3,3 9,9 1,3 3,11 10,10
10,10 3,11 3,3 9,9 7,7 8,8 8,1 1,1 8,1 8,8 7,7 9,9 3,3 1,3 3,11 10,10
10,10 11,11 3,3 7,7 8,8 8,1 0,0 8,1 8,8 7,7 3,3 11,11 10,10
10,10 11,11 3,3 9,9 7,7 8,8 8,1 8,8 7,7 9,9 3,3 11,11 10,10
10,10 11,11 3,3 9,9 3,3 7,7 3,3 9,9 3,3 11,11 10,10
10,10 11,11 3,3 9,9 3,3 11,11 3,3 9,9 3,3 11,11 10,10
11,11 3,3 9,9 3,3 11,11 10,10 11,11 3,3 9,9 3,3 11,11
11,11 3,3 9,9 3,3 11,11 10,10 11,11 10,10 11,11 3,3 9,9 3,3 11,11
11,11 3,3 9,9 3,3 11,11 10,10 11,11 10,10 11,11 10,10 11,11 3,3 9,9 3,3 11,11
11,11 3,3 9,9 3,3 11,11 10,10 11,11 10,10 11,11 3,3 9,9 3,3 11,11
10,10 11,11 3,3 9,9 3,3 11,11 10,10 11,11 3,3 9,9 3,3 11,11 10,10
10,10 11,11 3,3 9,9 3,3 11,11 3,3 9,9 3,3 11,11 10,10
10,10 11,11 3,3 9,9 3,3 9,9 3,3 11,11 10,10
10,10 11,11 3,3 9,9 3,3 11,11 10,10
10,10 11,11 3,3 11,11 10,10