#! /usr/bin/python
# -*- coding:utf-8 -*-
# © 2012 Skyler Lehmkuhl
# Released under the GPLv3. For more information, see gpl.txt.
import os, shutil, tarfile, tempfile, StringIO, urllib, subprocess
# Workaround for broken menubar under Ubuntu
os.putenv("UBUNTU_MENUPROXY", "0")
#Uncomment to build on OS X
#import objc, AppKit, cPickle
#Uncomment to build on Windows
#import ctypes, ctypes.wintypes, win32print
#SVLGUI - my custom GUI wrapper to abstract the GUI
import svlgui
#swift_window - builds the application windows
import lightningbeam_windows
#pickle - used to save and open files
import pickle
#webbrowser - used to launch HTML5
import webbrowser
#misc_funcs - miscelleneous functions in a separate file so as not to clutter things up too much
import misc_funcs
#If we can import this, we are in the install directory. Mangle media paths accordingly.
try:
from distpath import media_path
except:
media_path = ""
#specify the current version and what version files it can still open
LIGHTNINGBEAM_VERSION = "1.0-alpha1"
LIGHTNINGBEAM_COMPAT = ["1.0-alpha1"]
#Global variables. Used to keep stuff together.
global root
global layers
global undo_stack
global redo_stack
undo_stack = []
redo_stack = []
def clear(arr):
arr.__delslice__(0,len(arr))
def update_date():
return "Tue, January 10, 2012"
class edit:
def __init__(self, type, obj, from_attrs, to_attrs):
self.type = type
self.obj = obj
self.from_attrs = from_attrs
self.to_attrs = to_attrs
class maybe:
def __init__(self, type, obj, from_attrs):
self.edit = edit(type, obj, from_attrs, from_attrs)
self.type = type
def complete(self, to_attrs):
self.edit.to_attrs = to_attrs
return self.edit
svlgui.undo_stack = undo_stack
svlgui.edit = edit
svlgui.maybe = maybe
svlgui.clear = clear
def onLoadFrames(self):
'''for i in range(2000):
if i%5==0:
j = box(i*16,0,16,32,svlgui.Color([0.5,0.5,0.5]))
self.add(j)
else:
j = box(i*16,0,16,32,svlgui.Color([1,1,1]))
self.add(j)'''
def onClickFrame(self, x, y,button=1,clicks=1):
root.descendItem().activelayer.frames[root.descendItem().activelayer.currentframe].actions = MainWindow.scriptwindow.text
root.descendItem().activeframe = int(x/16)
print ">>>>>> ", x, y
MainWindow.stage.draw()
MainWindow.scriptwindow.text = str(root.descendItem().activelayer.frames[root.descendItem().activelayer.currentframe].actions)
def onKeyDownFrame(self, key):
root.descendItem().activelayer.frames[root.descendItem().activelayer.currentframe].actions = MainWindow.scriptwindow.text
if key in [" ", "s", "r", "e", "b"]:
svlgui.MODE=key
svlgui.set_cursor({" ":"arrow","s":"arrow","r":"crosshair","e":"crosshair",
"b":"arrow"}[key], MainWindow.stage)
misc_funcs.update_tooloptions()
elif key=="F6":
add_keyframe()
elif key=="F8":
convert_to_symbol()
MainWindow.scriptwindow.text = root.descendItem().activelayer.frames[root.descendItem().activelayer.currentframe].actions
def onMouseDownGroup(self, x, y,button=1,clicks=1):
self.activelayer.frames[self.activelayer.currentframe].actions = MainWindow.scriptwindow.text
if svlgui.MODE in [" ", "s"]:
if self.hitTest(x, y):
self.clicked = True
elif svlgui.MODE in ["r", "e", "p"]:
if svlgui.MODE=="r":
# 'c' stands for 'current'
self.cshape = box(x, y, 0, 0)
elif svlgui.MODE=="e":
self.cshape = ellipse(x, y, 0, 0)
elif svlgui.MODE=="p":
self.cshape = shape(x, y)
#self.cshape.rotation = 5
self.cshape.initx,self.cshape.inity = x, y
self.add(self.cshape)
self.cshape.onMouseDown = onMouseDownObj
self.cshape.onMouseMove = onMouseMoveObj
self.cshape.onMouseDrag = onMouseDragObj
self.cshape.onMouseUp = onMouseUpObj
self.cshape.onKeyDown = onKeyDownObj
undo_stack.append(maybe("add_object", self, {"frame":self.activelayer.currentframe, "layer":self.activelayer}))
self.clicked = True
MainWindow.scriptwindow.text = self.activelayer.frames[self.activelayer.currentframe].actions
elif svlgui.MODE in ["t"]:
self.ctext = svlgui.Text("Mimimi",x,y)
self.ctext.editing = True
svlgui.CURRENTTEXT = self.ctext
self.ctext.onMouseDown = onMouseDownText
self.ctext.onMouseDrag = onMouseDragText
self.ctext.onMouseUp = onMouseUpText
self.add(self.ctext)
self.ctext = None
undo_stack.append(edit("add_object", self, {"frame":self.activelayer.currentframe, "layer":self.activelayer}, \
{"frame":self.activelayer.currentframe, "layer":self.activelayer, \
"obj":self.activelayer.frames[self.activelayer.currentframe].objs[-1]}))
self.activelayer.currentselect = self.activelayer.frames[self.activelayer.currentframe].objs[-1]
MainWindow.docbox.setvisible(True)
MainWindow.textbox.setvisible(False)
def onMouseDownObj(self, x, y,button=1,clicks=1):
MainWindow.scriptwindow.text = root.descendItem().activelayer.frames[root.descendItem().activelayer.currentframe].actions
self.clicked = True
self.initx,self.inity = x-self.x, y-self.y
if svlgui.MODE == " ":
undo_stack.append(maybe("move", self, {"x":self.x, "y":self.y}))
elif svlgui.MODE == "s":
undo_stack.append(maybe("scale", self, {"x":self.x, "y":self.y, "xscale":self.xscale, "yscale":self.yscale}))
elif svlgui.MODE == "b":
if not (self.fillcolor.val == svlgui.FILLCOLOR.val and self.filled==True):
undo_stack.append(edit("fill", self, {"filled":self.filled, "fillcolor":self.fillcolor}, {"filled":True, "fillcolor":svlgui.FILLCOLOR}))
clear(redo_stack)
self.filled = True
self.fillcolor = svlgui.FILLCOLOR
def onMouseDownText(self,x,y,button=1,clicks=1):
MainWindow.scriptwindow.text = root.descendItem().activelayer.frames[root.descendItem().activelayer.currentframe].actions
self.clicked = True
self.initx, self.inity = x-self.x, y-self.y
MainWindow.docbox.setvisible(False)
MainWindow.textbox.setvisible(True)
svlgui.CURRENTTEXT = self.obj
if clicks>1:
self.obj.editing = True
def onMouseDownFrame(self, x, y,button=1,clicks=1):
pass
def onMouseUpGroup(self, x, y,button=1,clicks=1):
self.clicked = False
if svlgui.MODE in ["r", "e"]:
self.cshape = None
cobj = self.activelayer.frames[self.activelayer.currentframe].objs[-1]
if isinstance(undo_stack[-1], maybe):
if undo_stack[-1].edit.obj==self:
if undo_stack[-1].type=="add_object":
undo_stack[-1] = undo_stack[-1].complete({"obj":cobj, "frame":self.activelayer.currentframe, "layer":self.activelayer})
clear(redo_stack)
elif svlgui.MODE=="p":
print len(self.cshape.shapedata)
self.cshape.shapedata = misc_funcs.simplify_shape(self.cshape.shapedata, svlgui.PMODE.split()[-1],1)
print len(self.cshape.shapedata)
self.cshape = None
MainWindow.stage.draw()
def onMouseUpObj(self, x, y,button=1,clicks=1):
self.clicked = False
if isinstance(undo_stack[-1], maybe):
if undo_stack[-1].edit.obj==self:
if undo_stack[-1].type=="move":
if abs(self.x-undo_stack[-1].edit.from_attrs["x"])>0 or abs(self.y-undo_stack[-1].edit.from_attrs["y"])>0:
undo_stack[-1] = undo_stack[-1].complete({"x":self.x, "y":self.y})
clear(redo_stack)
else:
del undo_stack[-1]
elif undo_stack[-1].type=="scale":
if abs(self.x-undo_stack[-1].edit.from_attrs["x"])>0 or abs(self.y-undo_stack[-1].edit.from_attrs["y"])>0 \
or abs(self.xscale-undo_stack[-1].edit.from_attrs["xscale"])>0 or abs(self.yscale-undo_stack[-1].edit.from_attrs["yscale"])>0:
undo_stack[-1] = undo_stack[-1].complete({"x":self.x, "y":self.y, "xscale":self.xscale, "yscale":self.yscale})
clear(redo_stack)
else:
del undo_stack[-1]
def onMouseUpText(self, x, y,button=1,clicks=1):
self.clicked = False
def onMouseMoveGroup(self, x, y,button=1):
pass
#This is for testing rotation. Comment out before any commit!
#root.rotation+=0.01
def onMouseMoveObj(self, x, y,button=1):
pass
def onMouseDragGroup(self, x, y,button=1,clicks=1):
if svlgui.MODE in [" ", "s"]:
self.x = x
self.y = y
elif svlgui.MODE == "r":
sd = self.cshape.shapedata
x=x-self.cshape.initx
y=y-self.cshape.inity
self.cshape.shapedata = [sd[0],["L",x,sd[0][2]],["L",x,y],["L",sd[0][1],y],sd[4]]
elif svlgui.MODE == "e":
sd = self.cshape.shapedata
x=x-self.cshape.initx
y=y-self.cshape.inity
self.cshape.shapedata = [["M",x/2,0],["C",4*x/5,0,x,y/5,x,y/2],["C",x,4*y/5,4*x/5,y,x/2,y],["C",x/5,y,0,4*y/5,0,y/2],["C",0,y/5,x/5,0,x/2,0]]
elif svlgui.MODE == "p":
self.cshape.shapedata.append(["L",x-self.cshape.initx,y-self.cshape.inity])
def onMouseDragObj(self, x, y,button=1,clicks=1):
if svlgui.MODE==" ":
self.x = x-self.initx
self.y = y-self.inity
elif svlgui.MODE=="s":
if svlgui.SCALING:
# self.xscale = (x-(self.maxx/2.0+self.minx))/(self.maxx/2.0)
# self.yscale = (y-(self.maxy/2.0+self.miny))/(self.maxy/2.0)
if self.initx>self.maxx/2:
self.xscale = (x-self.x)/self.maxx
else:
# I don't understand why I need 2*self.maxx instead of just maxx, but it works.
self.xscale = (2*self.maxx+self.x-(x-self.initx)-x)/self.maxx
self.x = x
if self.inity>self.maxy/2:
self.yscale = (y-self.y)/self.maxy
else:
# 3 times?? Why??
self.yscale = (3*self.maxy+self.y-(y-self.inity)-y)/self.maxy
self.y = y
print self.initx
# self.xscale = ((self.maxx/2.0+self.minx)-x)/((self.maxx/2.0+self.minx)-self.initx)
# self.yscale = ((self.maxy/2.0+self.miny)-y)/((self.maxy/2.0+self.miny)-self.inity)
def onMouseDragText(self, x, y,button=1,clicks=1):
self.x = x-self.initx
self.y = y-self.inity
def onKeyDownGroup(self, key):
if not svlgui.EDITING:
if key in [" ", "s", "r", "e", "b", "p"]:
svlgui.MODE=key
svlgui.set_cursor({" ":"arrow","s":"arrow","r":"crosshair","e":"crosshair",
"b":"arrow","p":"arrow"}[key], MainWindow.stage)
misc_funcs.update_tooloptions()
elif key=="F6":
add_keyframe()
elif key=="F8":
convert_to_symbol()
else:
if not key=="escape":
pass
else:
svlgui.EDITING=False
def onKeyDownObj(self, key):
if key in ("delete", "backspace"):
del self.parent[self.parent.index(self)] # Need to clean up deletion
elif key in [" ", "s", "r", "e", "b", "p"]:
svlgui.MODE=key
svlgui.set_cursor({" ":"arrow","s":"arrow","r":"crosshair","e":"crosshair",
"b":"arrow","p":"arrow"}[key], MainWindow.stage)
misc_funcs.update_tooloptions()
elif key=="F6":
add_keyframe()
elif key=="F8":
convert_to_symbol()
elif key=="left_arrow":
self.x-=1
elif key=="right_arrow":
self.x+=1
elif key=="up_arrow":
self.y-=1
elif key=="down_arrow":
self.y+=1
def create_sc(root):
#retval = ".flash bbox="+str(svlgui.WIDTH)+"x"+str(svlgui.HEIGHT)+" background=#ffffff \
#fps="+str(svlgui.FRAMERATE)+"\n"+root.print_sc()+".end"
print svlgui.Library
retval = ".flash bbox="+str(svlgui.WIDTH)+"x"+str(svlgui.HEIGHT)+" background=#ffffff \
fps="+str(svlgui.FRAMERATE)+"\n"+"".join([i.print_sc() for i in svlgui.Library])+root.print_sc()+".end"
return retval
def run_file(self=None):
global root
print "RUNNING"
root.descendItem().activelayer.frames[root.descendItem().activelayer.currentframe].actions = MainWindow.scriptwindow.text
open(os.getenv('HOME')+"/test.sc", "w").write(create_sc(root))
svlgui.execute("swfc/swfc_"+svlgui.PLATFORM+" "+os.getenv('HOME')+"/test.sc -o "+os.getenv('HOME')+"/test.swf")
#TODO: Make this cross-platform compatible
if svlgui.PLATFORM=="win32":
# Untested.
logloc = os.getenv('HOME')+"\\AppData\\Roaming\\Macromedia\\Flash Player\\Logs\\flashlog.txt"
elif "linux" in svlgui.PLATFORM:
if not os.path.exists(os.getenv('HOME')+"/mm.cfg"):
# By default, the Flash debugger on Linux does not log traces.
# So, we create a configuration file to tell it to do so if the user hasn't already.
with open(os.getenv('HOME')+"/mm.cfg", "w") as mm:
mm.write("ErrorReportingEnable=1\nTraceOutputFileEnable=1")
logloc = os.getenv('HOME')+"/.macromedia/Flash_Player/Logs/flashlog.txt"
elif svlgui.PLATFORM=="osx":
logloc = os.getenv('HOME')+"/Library/Preferences/Macromedia/Flash Player/Logs/flashlog.txt"
if not os.path.exists('/Applications/Flash Player Debugger.app'):
# check for Flash Player
result = svlgui.alert("You do not have a Flash debugger installed. Install one?", confirm=True)
if not result:
svlgui.alert("Aborting.")
return
else:
svlgui.alert("The file will download when you click Ok.\nThis may take some time.")
urllib.urlretrieve("http://fpdownload.macromedia.com/pub/flashplayer/updaters/11/flashplayer_11_sa_debug.app.zip", "fp.app.zip")
# Unzip the file. Apparently ditto is better for OSX apps than unzip.
os.system('ditto -V -x -k --sequesterRsrc --rsrc fp.app.zip .')
shutil.move('Flash Player Debugger.app', '/Applications')
# Generally it is not recognized until it is opened
os.system('open -a "/Applications/Flash Player Debugger.app"')
# Set Flash Player Debugger as the default app for .swf files
os.system('defaults write com.apple.LaunchServices LSHandlers -array-add "