help im trapped inside the commit message oh hey who are OH NO AHHHHHH STOP NO DONT DO THAT AHHHHHHHHHHHHHHHHHH IM BLEEDING
2
ENNTool/.gitignore
vendored
@ -1,2 +0,0 @@
|
|||||||
__pycache__/
|
|
||||||
*.sw[op]
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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>
|
|
Before Width: | Height: | Size: 1.5 MiB |
@ -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
|
|
@ -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 Cisco’s 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 user’s device, and not integrated into or combined with third party software prior to being downloaded to the end user’s 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
|
|
Before Width: | Height: | Size: 51 KiB |
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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/>
|
|
Before Width: | Height: | Size: 360 B |
Before Width: | Height: | Size: 227 B |
Before Width: | Height: | Size: 271 B |
Before Width: | Height: | Size: 277 B |
Before Width: | Height: | Size: 250 B |
Before Width: | Height: | Size: 265 B |
Before Width: | Height: | Size: 289 B |
Before Width: | Height: | Size: 249 B |
Before Width: | Height: | Size: 527 B |
Before Width: | Height: | Size: 236 B |
Before Width: | Height: | Size: 290 B |
Before Width: | Height: | Size: 232 B |
Before Width: | Height: | Size: 246 B |
Before Width: | Height: | Size: 282 B |
Before Width: | Height: | Size: 236 B |
Before Width: | Height: | Size: 371 B |
Before Width: | Height: | Size: 213 B |
Before Width: | Height: | Size: 220 B |
Before Width: | Height: | Size: 306 B |
@ -2,24 +2,7 @@
|
|||||||
#
|
#
|
||||||
# mirc2png -- convert ASCII w/ mIRC control codes to monospaced PNG (for EFnet #MiRCART)
|
# mirc2png -- convert ASCII w/ mIRC control codes to monospaced PNG (for EFnet #MiRCART)
|
||||||
# Copyright (c) 2018 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
|
# Copyright (c) 2018 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
|
||||||
#
|
# This project is licensed under the terms of the MIT licence.
|
||||||
# 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 itertools import chain
|
from itertools import chain
|
@ -2,24 +2,7 @@
|
|||||||
#
|
#
|
||||||
# IrcMiRCARTBot.py -- IRC<->MiRC2png bot (for EFnet #MiRCART)
|
# IrcMiRCARTBot.py -- IRC<->MiRC2png bot (for EFnet #MiRCART)
|
||||||
# Copyright (c) 2018 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
|
# Copyright (c) 2018 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
|
||||||
#
|
# This project is licensed under the terms of the MIT licence.
|
||||||
# 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 getopt import getopt, GetoptError
|
from getopt import getopt, GetoptError
|
0
ENNTool/LICENCE → asciiblaster-python/LICENCE
Normal file → Executable file
@ -2,24 +2,7 @@
|
|||||||
#
|
#
|
||||||
# MiRCARTCanonicalise.py -- canonicalise mIRC art {from,to} file (for munki)
|
# MiRCARTCanonicalise.py -- canonicalise mIRC art {from,to} file (for munki)
|
||||||
# Copyright (c) 2018 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
|
# Copyright (c) 2018 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
|
||||||
#
|
# This project is licensed under the terms of the MIT licence.
|
||||||
# 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 MiRCARTCanvasImportStore import MiRCARTCanvasImportStore
|
from MiRCARTCanvasImportStore import MiRCARTCanvasImportStore
|
@ -2,24 +2,7 @@
|
|||||||
#
|
#
|
||||||
# MiRCARTCanvasImportStore.py -- XXX
|
# MiRCARTCanvasImportStore.py -- XXX
|
||||||
# Copyright (c) 2018 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
|
# Copyright (c) 2018 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
|
||||||
#
|
# This project is licensed under the terms of the MIT licence.
|
||||||
# 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 MiRCARTCanvasImportStore():
|
class MiRCARTCanvasImportStore():
|
17
asciiblaster-python/MiRCARTCheckLineLengths.sh
Executable 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
|
11
asciiblaster-python/MiRCARTImgurApiKey.py.template
Normal 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
|
@ -2,24 +2,7 @@
|
|||||||
#
|
#
|
||||||
# MiRCARTToPngFile.py -- convert ASCII w/ mIRC control codes to monospaced PNG (for EFnet #MiRCART)
|
# 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>
|
# Copyright (c) 2018 Lucio Andrés Illanes Albornoz <lucio@lucioillanes.de>
|
||||||
#
|
# This project is licensed under the terms of the MIT licence.
|
||||||
# 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 MiRCARTCanvasImportStore
|
import MiRCARTCanvasImportStore
|
12
asciiblaster-python/MiRCARTToPngFiles.sh
Executable 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
@ -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
@ -1,2 +0,0 @@
|
|||||||
__pycache__/
|
|
||||||
*.sw[op]
|
|
19
mawj/LICENCE
@ -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.
|
|
@ -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
|
|
334
mawj/mawj.py
@ -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
|
|
@ -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
|
|