Merge branch 'master' of github.com:skykooler/Lightningbeam

This commit is contained in:
Skyler Lehmkuhl 2013-08-06 11:43:22 -04:00
commit 605d1a4c46
12 changed files with 625 additions and 109 deletions

View File

@ -42,7 +42,8 @@ class Canvas(Properties):
self.textcolor = c self.textcolor = c
def rmoveto(self, dx, dy): def rmoveto(self, dx, dy):
x0, y0 = self._current_point() x0, y0 = self._current_point
# x0, y0 = self._current_point()
self.moveto(x0 + dx, y0 + dy) self.moveto(x0 + dx, y0 + dy)
def rlineto(self, dx, dy): def rlineto(self, dx, dy):

View File

@ -171,10 +171,9 @@ class Canvas(GCanvas, GCanvasPaths):
#ctx.set_source_rgba(*self._state.fillcolor._rgba) #ctx.set_source_rgba(*self._state.fillcolor._rgba)
if self.fillcolor.image: if self.fillcolor.image:
# surface = # surface =
ctx.set_source_pixbuf(self.fillcolor.image, 0, 0)
ctx.save() ctx.save()
print (self.maxx-self.minx)*1.0/self.fillcolor.image.get_width() ctx.scale((self.maxx-self.minx)*1.0/self.fillcolor.image.get_width(), (self.maxy-self.miny)*1.0/self.fillcolor.image.get_height())
self._gtk_ctx.scale((self.maxx-self.minx)*1.0/self.fillcolor.image.get_width(), 1) ctx.set_source_pixbuf(self.fillcolor.image, 0, 0)
ctx.fill_preserve() ctx.fill_preserve()
ctx.restore() ctx.restore()
else: else:

View File

@ -5,6 +5,7 @@
#-------------------------------------------------------------------- #--------------------------------------------------------------------
from math import sin, cos, pi from math import sin, cos, pi
import sys
import win32con as wc, win32ui as ui, win32gui as gui import win32con as wc, win32ui as ui, win32gui as gui
from win32con import PS_SOLID, BS_SOLID, RGN_AND from win32con import PS_SOLID, BS_SOLID, RGN_AND
#from win32ui import CreatePen, CreateBrush #from win32ui import CreatePen, CreateBrush
@ -119,6 +120,10 @@ class Canvas(GCanvas):
def set_fillcolor(self, c): def set_fillcolor(self, c):
state = self._state state = self._state
state.fillcolor = c state.fillcolor = c
if self.fillcolor.image:
tb = gdip.TextureBrush(self.fillcolor.image)
state.win_fill_brush = tb
else:
state.win_fill_brush = gdip.SolidBrush(c._win_argb) state.win_fill_brush = gdip.SolidBrush(c._win_argb)
def get_textcolor(self): def get_textcolor(self):
@ -156,19 +161,41 @@ class Canvas(GCanvas):
def newpath(self): def newpath(self):
self._win_path.Reset() self._win_path.Reset()
self.minx = sys.maxint
self.miny = sys.maxint
self.maxx = -sys.maxint/2
self.maxy = -sys.maxint/2
def moveto(self, x, y): def moveto(self, x, y):
p = (x, y) p = (x, y)
try:
self.minx = min(self.minx, x)
self.miny = min(self.miny, y)
self.maxx = max(self.maxx, x)
self.maxy = max(self.maxy, y)
except AttributeError:
self.minx = x
self.miny = y
self.maxx = x
self.maxy = y
self._current_point = p self._current_point = p
self._win_path.StartFigure() self._win_path.StartFigure()
def lineto(self, x, y): def lineto(self, x, y):
x0, y0 = self._current_point x0, y0 = self._current_point
self.minx = min(self.minx, x)
self.miny = min(self.miny, y)
self.maxx = max(self.maxx, x)
self.maxy = max(self.maxy, y)
self._win_path.AddLine_4f(x0, y0, x, y) self._win_path.AddLine_4f(x0, y0, x, y)
self._current_point = (x, y) self._current_point = (x, y)
def curveto(self, p1, p2, p3): def curveto(self, p1, p2, p3):
p0 = self._current_point p0 = self._current_point
self.minx = min(self.minx, p1[0], p2[0], p3[0])
self.miny = min(self.miny, p1[1], p2[1], p3[1])
self.maxx = max(self.maxx, p1[0], p2[0], p3[0])
self.maxy = max(self.maxy, p1[1], p2[1], p3[1])
self._win_path.AddBezier_4p(p0, p1, p2, p3) self._win_path.AddBezier_4p(p0, p1, p2, p3)
self._current_point = p3 self._current_point = p3
@ -182,6 +209,12 @@ class Canvas(GCanvas):
self._current_point = None self._current_point = None
def fill(self): def fill(self):
if self.fillcolor.image:
self.gsave()
self._win_graphics.Scale_2f((self.maxx-self.minx)*1.0/self.fillcolor.image.GetWidth(), (self.maxy-self.miny)*1.0/self.fillcolor.image.GetHeight())
self._win_graphics.FillPath(self._state.win_fill_brush, self._win_path)
self.grestore()
else:
self._win_graphics.FillPath(self._state.win_fill_brush, self._win_path) self._win_graphics.FillPath(self._state.win_fill_brush, self._win_path)
def stroke(self): def stroke(self):

View File

@ -7,8 +7,12 @@
import win32con as wc, win32api as api import win32con as wc, win32api as api
from GUI import Color from GUI import Color
def rgb(red, green, blue, alpha = 1.0): def rgb(red, green, blue, alpha = 1.0, image = False, im = ''):
color = Color() color = Color()
color.image = image
if image:
color.image = im._win_image
else:
color._red = red color._red = red
color._green = green color._green = green
color._blue = blue color._blue = blue

View File

@ -159,6 +159,21 @@ class SolidBrush(object):
#-------------------------------------------------------------------- #--------------------------------------------------------------------
class TextureBrush(object):
def __init__(self, image):
ptr = c_void_p()
wg.GdipCreateTexture(image.ptr, 4, byref(ptr))
self.ptr = ptr
def __del__(self, wg = wg):
wg.GdipDeleteBrush(self.ptr)
def __str__(self):
return "<TextureBrush>"
#--------------------------------------------------------------------
class Font(object): class Font(object):
def __init__(self, family, size, style): def __init__(self, family, size, style):

View File

@ -1,10 +1,10 @@
Building on Windows: Building on Windows:
1. In a CMD window, type: 1. Uncomment the line at the beginning of lightningbeam.py that says "Uncomment to build on Windows"
2. In a CMD window, type:
c:\Python27\python.exe setup.py py2exe c:\Python27\python.exe setup.py py2exe
2. Copy the GUI folder from the root directory into dist\. 4. The executable is in dist\lightningbeam.exe. You probably do need most of the DLL's, I haven't
3. The executable is in dist\lightningbeam.exe. You probably do need most of the DLL's, I haven't
gone through them yet. gone through them yet.
Building on Ubuntu/Debian: Building on Ubuntu/Debian:

View File

@ -83,12 +83,13 @@ class PyGUIFormatter(Formatter):
class CodeEditor(ScrollableView): class CodeEditor(ScrollableView):
def __init__(self): def __init__(self):
ScrollableView.__init__(self) ScrollableView.__init__(self)
self.text = "var a = {b:5, c:[3, 'df \\'']};\n_xscale\nif (this.hitTest(_root._xmouse, root._ymouse, false)) {\n\n\ttrace('hi');\n}" self.text = "_root.onMouseDown = function () {\n\ttrace('Hi');\n};"
self.font = Font('Courier', 16) self.font = Font('Courier', 16)
self.selecting = False self.selecting = False
self.lexer = ActionScriptLexer() self.lexer = ActionScriptLexer()
self.cursorpos = 0 self.cursorpos = 0
self.scursorpos = 0 self.scursorpos = 0
self.selection = (0,0)
self.formatter = PyGUIFormatter() self.formatter = PyGUIFormatter()
# self.filter = NameHighlightFilter( # self.filter = NameHighlightFilter(
self.filter = EverythingHighlightFilter( self.filter = EverythingHighlightFilter(
@ -169,6 +170,7 @@ class CodeEditor(ScrollableView):
except: except:
pass pass
self.scursorpos = self.cursorpos self.scursorpos = self.cursorpos
self.selection = (self.cursorpos, self.cursorpos)
if int(y/self.font.height): if int(y/self.font.height):
self.cursorpos+=1 self.cursorpos+=1
self.invalidate_rect([0,0,self.extent[0],self.extent[1]]) self.invalidate_rect([0,0,self.extent[0],self.extent[1]])
@ -183,6 +185,7 @@ class CodeEditor(ScrollableView):
pass pass
if int(y/self.font.height): if int(y/self.font.height):
self.cursorpos+=1 self.cursorpos+=1
self.selection = (min(self.cursorpos, self.scursorpos), max(self.cursorpos, self.scursorpos))
self.invalidate_rect([0,0,self.extent[0],self.extent[1]]) self.invalidate_rect([0,0,self.extent[0],self.extent[1]])
def key_down(self, event): def key_down(self, event):
keydict = {127:"backspace",63272:"delete",63232:"up_arrow",63233:"down_arrow", keydict = {127:"backspace",63272:"delete",63232:"up_arrow",63233:"down_arrow",
@ -241,6 +244,8 @@ class CodeEditor(ScrollableView):
else: else:
self.text=self.text[:self.cursorpos]+str(key)+self.text[self.cursorpos:] self.text=self.text[:self.cursorpos]+str(key)+self.text[self.cursorpos:]
self.cursorpos += 1 self.cursorpos += 1
self.scursorpos = self.cursorpos
self.selection = (self.cursorpos, self.cursorpos)
self.invalidate_rect([0,0,self.extent[0],self.extent[1]]) self.invalidate_rect([0,0,self.extent[0],self.extent[1]])
class test(Application): class test(Application):
def __init__(self): def __init__(self):

View File

@ -49,6 +49,8 @@ global undo_stack
global redo_stack global redo_stack
undo_stack = [] undo_stack = []
redo_stack = [] redo_stack = []
global preferences
preferences={}
def clear(arr): def clear(arr):
arr.__delslice__(0,len(arr)) arr.__delslice__(0,len(arr))
@ -108,6 +110,7 @@ def onMouseDownGroup(self, x, y,button=1,clicks=1):
if svlgui.MODE in [" ", "s"]: if svlgui.MODE in [" ", "s"]:
if self.hitTest(x, y): if self.hitTest(x, y):
self.clicked = True self.clicked = True
elif svlgui.MODE in ["r", "e", "p"]: elif svlgui.MODE in ["r", "e", "p"]:
if svlgui.MODE=="r": if svlgui.MODE=="r":
# 'c' stands for 'current' # 'c' stands for 'current'
@ -115,7 +118,19 @@ def onMouseDownGroup(self, x, y,button=1,clicks=1):
elif svlgui.MODE=="e": elif svlgui.MODE=="e":
self.cshape = ellipse(x, y, 0, 0) self.cshape = ellipse(x, y, 0, 0)
elif svlgui.MODE=="p": elif svlgui.MODE=="p":
self.cshape = shape(x, y) # self.cshape = shape(x, y)
self.cshape = svlgui.Line(svlgui.Point(x, y),svlgui.Point(x,y))
for i in self.lines:
if abs(self.cshape.endpoint1.x-i.endpoint1.x)<10 and abs(self.cshape.endpoint1.y-i.endpoint1.y)<10:
self.cshape.connection1 = i.endpoint1
self.cshape.connection1.lines.add(self.cshape)
break
elif abs(self.cshape.endpoint1.x-i.endpoint2.x)<10 and abs(self.cshape.endpoint1.y-i.endpoint2.y)<10:
self.cshape.connection1 = i.endpoint2
self.cshape.connection1.lines.add(self.cshape)
break
self.lines.append(self.cshape)
return
#self.cshape.rotation = 5 #self.cshape.rotation = 5
self.cshape.initx,self.cshape.inity = x, y self.cshape.initx,self.cshape.inity = x, y
self.add(self.cshape) self.add(self.cshape)
@ -182,9 +197,18 @@ def onMouseUpGroup(self, x, y,button=1,clicks=1):
undo_stack[-1] = undo_stack[-1].complete({"obj":cobj, "frame":self.activelayer.currentframe, "layer":self.activelayer}) undo_stack[-1] = undo_stack[-1].complete({"obj":cobj, "frame":self.activelayer.currentframe, "layer":self.activelayer})
clear(redo_stack) clear(redo_stack)
elif svlgui.MODE=="p": elif svlgui.MODE=="p":
print len(self.cshape.shapedata) '''print len(self.cshape.shapedata)
self.cshape.shapedata = misc_funcs.simplify_shape(self.cshape.shapedata, svlgui.PMODE.split()[-1],1) self.cshape.shapedata = misc_funcs.simplify_shape(self.cshape.shapedata, svlgui.PMODE.split()[-1],1)
print len(self.cshape.shapedata) print len(self.cshape.shapedata)'''
for i in self.lines:
if abs(self.cshape.endpoint2.x-i.endpoint1.x)<10 and abs(self.cshape.endpoint2.y-i.endpoint1.y)<10:
self.cshape.connection2 = i.endpoint1
self.cshape.connection2.lines.add(self.cshape)
break
elif abs(self.cshape.endpoint2.x-i.endpoint2.x)<10 and abs(self.cshape.endpoint2.y-i.endpoint2.y)<10:
self.cshape.connection2 = i.endpoint2
self.cshape.connection2.lines.add(self.cshape)
break
self.cshape = None self.cshape = None
MainWindow.stage.draw() MainWindow.stage.draw()
def onMouseUpObj(self, x, y,button=1,clicks=1): def onMouseUpObj(self, x, y,button=1,clicks=1):
@ -243,7 +267,9 @@ def onMouseDragGroup(self, x, y,button=1,clicks=1):
y=y-self.cshape.inity 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]] 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": elif svlgui.MODE == "p":
self.cshape.shapedata.append(["L",x-self.cshape.initx,y-self.cshape.inity]) # self.cshape.shapedata.append(["L",x-self.cshape.initx,y-self.cshape.inity])
self.cshape.endpoint2.x = x
self.cshape.endpoint2.y = y
def onMouseDragObj(self, x, y,button=1,clicks=1): def onMouseDragObj(self, x, y,button=1,clicks=1):
if svlgui.MODE==" ": if svlgui.MODE==" ":
self.x = x-self.initx self.x = x-self.initx
@ -324,15 +350,19 @@ fps="+str(svlgui.FRAMERATE)+"\n"+"".join([i.print_sc() for i in svlgui.Library])
def run_file(self=None): def run_file(self=None):
global root global root
print "RUNNING" print "RUNNING"
print svlgui.FILE.name
root.descendItem().activelayer.frames[root.descendItem().activelayer.currentframe].actions = MainWindow.scriptwindow.text root.descendItem().activelayer.frames[root.descendItem().activelayer.currentframe].actions = MainWindow.scriptwindow.text
open(os.getenv('HOME')+"/test.sc", "w").write(create_sc(root)) # open(os.getenv('HOME')+"/test.sc", "w").write(create_sc(root))
open(svlgui.FILE.name+".sc", "w").write(create_sc(root))
# svlgui.execute("swfc/swfc_"+svlgui.PLATFORM+" "+os.getenv('HOME')+"/test.sc -o "+os.getenv('HOME')+"/test.swf") # svlgui.execute("swfc/swfc_"+svlgui.PLATFORM+" "+os.getenv('HOME')+"/test.sc -o "+os.getenv('HOME')+"/test.swf")
x = os.system("swfc/swfc_"+svlgui.PLATFORM+" "+os.getenv('HOME')+"/test.sc -o "+os.getenv('HOME')+"/test.swf") # x = os.system("swfc/swfc_"+svlgui.PLATFORM+" "+os.getenv('HOME')+"/test.sc -o "+os.getenv('HOME')+"/test.swf")
x = os.system("swfc"+svlgui.sep+"swfc_"+svlgui.PLATFORM+" "+svlgui.FILE.name+".sc -o "+svlgui.FILE.name+".swf")
if sys.version_info < (2, 6): if sys.version_info < (2, 6):
if x==5: # which is the error value returned when linking libjpeg fails if x==5: # which is the error value returned when linking libjpeg fails
if svlgui.alert("You appear to be missing libjpeg. Install it?", confirm=True): if svlgui.alert("You appear to be missing libjpeg. Install it?", confirm=True):
os.system("""osascript -e 'do shell script "mkdir -p /usr/local/lib; cp swfc/libjpeg.8.dylib /usr/local/lib" with administrator privileges'""") os.system("""osascript -e 'do shell script "mkdir -p /usr/local/lib; cp swfc/libjpeg.8.dylib /usr/local/lib" with administrator privileges'""")
x = os.system("swfc/swfc_"+svlgui.PLATFORM+" "+os.getenv('HOME')+"/test.sc -o "+os.getenv('HOME')+"/test.swf") # x = os.system("swfc/swfc_"+svlgui.PLATFORM+" "+os.getenv('HOME')+"/test.sc -o "+os.getenv('HOME')+"/test.swf")
x = os.system("swfc/swfc_"+svlgui.PLATFORM+" "+svlgui.FILE.name+".sc -o "+svlgui.FILE.name+".swf")
if x==5: if x==5:
svlgui.alert("Sorry, something has gone terribly wrong.") svlgui.alert("Sorry, something has gone terribly wrong.")
else: else:
@ -340,14 +370,42 @@ def run_file(self=None):
#TODO: Make this cross-platform compatible #TODO: Make this cross-platform compatible
if svlgui.PLATFORM=="win32": if svlgui.PLATFORM=="win32":
# Untested. # Untested.
logloc = os.getenv('HOME')+"\\AppData\\Roaming\\Macromedia\\Flash Player\\Logs\\flashlog.txt" logloc = os.path.expanduser("~")+"\\AppData\\Roaming\\Macromedia\\Flash Player\\Logs\\flashlog.txt"
if not os.path.exists(os.path.expanduser("~")+"\\flashplayerdebugger.exe"):
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 Flash Debugger will download when you click Ok.\nThis may take some time.")
urllib.urlretrieve("http://download.macromedia.com/pub/flashplayer/updaters/11/flashplayer_11_sa_debug.exe", os.path.expanduser("~")+"\\flashplayerdebugger.exe")
if not os.path.exists(os.path.expanduser('~')+'\\mm.cfg'):
with open(os.path.expanduser('~')+"/mm.cfg", "w") as mm:
mm.write("ErrorReportingEnable=1\nTraceOutputFileEnable=1")
elif "linux" in svlgui.PLATFORM: elif "linux" in svlgui.PLATFORM:
logloc = os.getenv('HOME')+"/.macromedia/Flash_Player/Logs/flashlog.txt"
if not os.path.exists('/usr/bin/flashplayerdebugger'):
if os.system('which gnash')==0:
if not 'use_gnash' in preferences:
if svlgui.alert("You have GNASH installed. Do you wish to use it instead of Adobe's flash player?", confirm=True):
use_gnash = True
return
else:
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 Flash Debugger will download when you click Ok.\nThis may take some time.")
if not "PPC" in svlgui.PLATFORM:
urllib.urlretrieve("http://fpdownload.macromedia.com/pub/flashplayer/updaters/11/flashplayer_11_sa_debug.i386.tar.gz", "fp.tar.gz")
os.system("tar -zxf fp.tar.gz")
os.system("gksudo mv flashplayerdebugger /usr/bin/")
if not os.path.exists(os.getenv('HOME')+"/mm.cfg"): if not os.path.exists(os.getenv('HOME')+"/mm.cfg"):
# By default, the Flash debugger on Linux does not log traces. # 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. # 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: with open(os.getenv('HOME')+"/mm.cfg", "w") as mm:
mm.write("ErrorReportingEnable=1\nTraceOutputFileEnable=1") mm.write("ErrorReportingEnable=1\nTraceOutputFileEnable=1")
logloc = os.getenv('HOME')+"/.macromedia/Flash_Player/Logs/flashlog.txt"
elif svlgui.PLATFORM=="osx": elif svlgui.PLATFORM=="osx":
logloc = os.getenv('HOME')+"/Library/Preferences/Macromedia/Flash Player/Logs/flashlog.txt" logloc = os.getenv('HOME')+"/Library/Preferences/Macromedia/Flash Player/Logs/flashlog.txt"
if not os.path.exists('/Applications/Flash Player Debugger.app'): if not os.path.exists('/Applications/Flash Player Debugger.app'):
@ -399,21 +457,31 @@ def run_file(self=None):
outputtext.scroll_bottom() # this doesn't work outputtext.scroll_bottom() # this doesn't work
except: except:
pass pass
return True
if hasattr(svlgui, 'gobject'):
svlgui.gobject.timeout_add(20, updatetrace, outputtext)
else:
r = misc_funcs.RepeatTimer(0.02, updatetrace, args=[outputtext]) r = misc_funcs.RepeatTimer(0.02, updatetrace, args=[outputtext])
print dir(outputwin.window)
r.daemon = True r.daemon = True
r.start() r.start()
if svlgui.PLATFORM=="osx": if svlgui.PLATFORM=="osx":
osx_flash_player_loc = "/Applications/Flash\ Player\ Debugger.app" osx_flash_player_loc = "/Applications/Flash\ Player\ Debugger.app"
success = svlgui.execute("open -a "+osx_flash_player_loc+" "+os.getenv('HOME')+"/test.swf") # success = svlgui.execute("open -a "+osx_flash_player_loc+" "+os.getenv('HOME')+"/test.swf")
success = svlgui.execute("open -a "+osx_flash_player_loc+" "+svlgui.FILE.name+".swf")
if not success: if not success:
svlgui.alert("Oops! Didn't work. I probably couldn't find your Flash debugger!") svlgui.alert("Oops! Didn't work. I probably couldn't find your Flash debugger!")
elif svlgui.PLATFORM=='win32': elif svlgui.PLATFORM=='win32':
win_flash_player_loc = "" win_flash_player_loc = os.path.expanduser("~")+"\\flashplayerdebugger.exe"
svlgui.execute('start '+win_flash_player_loc+" test.swf") # svlgui.execute('start '+win_flash_player_loc+" test.swf")
svlgui.execute('start '+win_flash_player_loc+" "+svlgui.FILE.name+".swf")
elif svlgui.PLATFORM.startswith('linux'): elif svlgui.PLATFORM.startswith('linux'):
linux_flash_player_loc = "" linux_flash_player_loc = "/usr/bin/flashplayerdebugger"
svlgui.execute("xdg-open "+linux_flash_player_loc+" "+os.getenv('HOME')+"/test.swf") # if not svlgui.execute(linux_flash_player_loc+" "+os.getenv('HOME')+"/test.swf &"):
if not svlgui.execute(linux_flash_player_loc+" "+svlgui.FILE.name+".swf &"):
if '64' in svlgui.PLATFORM:
svlgui.alert("Flash debugger failed to launch! Try installing ia32-libs.")
elif '32' in svlgui.PLATFORM:
svlgui.alert("Flash debugger failed to launch! No idea why.")
def create_html5(root): def create_html5(root):
retval = "<head>\n\ retval = "<head>\n\
<style type=\"text/css\">\n\ <style type=\"text/css\">\n\
@ -539,7 +607,11 @@ def open_file(widget=None):
global root global root
MainWindow.stage.delete(root) MainWindow.stage.delete(root)
shutil.rmtree(svlgui.SECURETEMPDIR) shutil.rmtree(svlgui.SECURETEMPDIR)
try:
thetarfile = tarfile.open(fileobj=svlgui.file_dialog("open").open("rb"),mode="r:gz") thetarfile = tarfile.open(fileobj=svlgui.file_dialog("open").open("rb"),mode="r:gz")
except AttributeError:
# User cancelled
return
basefile = thetarfile.extractfile("basefile") basefile = thetarfile.extractfile("basefile")
root, svlgui.Library = pickle.load(basefile) root, svlgui.Library = pickle.load(basefile)
svlgui.SECURETEMPDIR = tempfile.mkdtemp() svlgui.SECURETEMPDIR = tempfile.mkdtemp()
@ -566,8 +638,11 @@ def save_file(widget=None):
tarinfo = tarfile.TarInfo('basefile') tarinfo = tarfile.TarInfo('basefile')
tarinfo.size = len(data) tarinfo.size = len(data)
if svlgui.FILE.name.startswith(svlgui.TEMPDIR): if svlgui.FILE.name.startswith(svlgui.TEMPDIR):
try:
thetarfile = tarfile.open(fileobj=svlgui.file_dialog("save", name="untitled.beam").open('wb'),mode="w:gz") thetarfile = tarfile.open(fileobj=svlgui.file_dialog("save", name="untitled.beam").open('wb'),mode="w:gz")
print thetarfile.name except AttributeError:
# User cancelled
return
else: else:
thetarfile = tarfile.open(svlgui.FILE.name,mode="w:gz") thetarfile = tarfile.open(svlgui.FILE.name,mode="w:gz")
thetarfile.addfile(tarinfo, StringIO.StringIO(data)) thetarfile.addfile(tarinfo, StringIO.StringIO(data))
@ -607,7 +682,11 @@ def save_file_as(widget=None):
data = pickle.dumps((root,svlgui.Library)) data = pickle.dumps((root,svlgui.Library))
tarinfo = tarfile.TarInfo('basefile') tarinfo = tarfile.TarInfo('basefile')
tarinfo.size = len(data) tarinfo.size = len(data)
try:
thetarfile = tarfile.open(fileobj=svlgui.file_dialog("save", name="untitled.beam").open('wb'),mode="w:gz") thetarfile = tarfile.open(fileobj=svlgui.file_dialog("save", name="untitled.beam").open('wb'),mode="w:gz")
except AttributeError:
# User cancelled
return
thetarfile.addfile(tarinfo, StringIO.StringIO(data)) thetarfile.addfile(tarinfo, StringIO.StringIO(data))
#Save the path so we can come back here #Save the path so we can come back here
lastpath = os.path.abspath(".") lastpath = os.path.abspath(".")
@ -629,7 +708,11 @@ def save_file_as(widget=None):
svlgui.FILE = thetarfile svlgui.FILE = thetarfile
pass pass
def import_to_stage(widget=None): def import_to_stage(widget=None):
thefile = svlgui.file_dialog("open",None,["jpg","png","bmp","wav"]).path try:
thefile = svlgui.file_dialog("open",None,["jpg","png","bmp","wav","mp3","ogg"]).path
except AttributeError:
# User cancelled
return
for i in ("jpg","png","bmp"): for i in ("jpg","png","bmp"):
if thefile.endswith(i): if thefile.endswith(i):
# im = svlgui.Image(thefile) # im = svlgui.Image(thefile)
@ -638,9 +721,17 @@ def import_to_stage(widget=None):
os.system("sips -s format png "+thefile+" --out "+svlgui.SECURETEMPDIR+"/"+".".join(thefile.split("/")[-1].split(".")[:-1])+".png") os.system("sips -s format png "+thefile+" --out "+svlgui.SECURETEMPDIR+"/"+".".join(thefile.split("/")[-1].split(".")[:-1])+".png")
elif "linux" in svlgui.PLATFORM: elif "linux" in svlgui.PLATFORM:
os.system("convert "+thefile+" "+svlgui.SECURETEMPDIR+"/"+".".join(thefile.split("/")[-1].split(".")[:-1])+".png") os.system("convert "+thefile+" "+svlgui.SECURETEMPDIR+"/"+".".join(thefile.split("/")[-1].split(".")[:-1])+".png")
thefile = svlgui.SECURETEMPDIR+"/"+".".join(thefile.split("/")[-1].split(".")[:-1])+".png" elif svlgui.PLATFORM=="win32":
from PIL import Image
im = Image.open(thefile)
# Use alpha channel if available (e.g. GIF)
transparency = im.info["transparency"] if 'transparency' in im.info else None
if transparency:
im.save(svlgui.SECURETEMPDIR+"\\"+".".join(thefile.split("\\")[-1].split(".")[:-1])+".png", transparency=transparency)
else:
im.save(svlgui.SECURETEMPDIR+"\\"+".".join(thefile.split("\\")[-1].split(".")[:-1])+".png")
thefile = svlgui.SECURETEMPDIR+svlgui.sep+".".join(thefile.split(svlgui.sep)[-1].split(".")[:-1])+".png"
im = box(100,100,200,200,svlgui.Color(thefile)) im = box(100,100,200,200,svlgui.Color(thefile))
print im.filled
im.onMouseDown = onMouseDownObj im.onMouseDown = onMouseDownObj
im.onMouseMove = onMouseMoveObj im.onMouseMove = onMouseMoveObj
im.onMouseDrag = onMouseDragObj im.onMouseDrag = onMouseDragObj
@ -649,7 +740,31 @@ def import_to_stage(widget=None):
root.descendItem().add(im) root.descendItem().add(im)
break break
else: else:
if thefile.endswith("wav"): for i in ("wav", "mp3", "ogg"):
if thefile.endswith(i):
if i in ("mp3", "ogg"):
if svlgui.PLATFORM=="win32":
if os.system("C:\\Progra~2\\MPlayer\\mplayer.exe")!=0:
if os.system("C:\\Progra~1\\MPlayer\\mplayer.exe")!=0:
result = svlgui.alert("To import mp3 and ogg files you must install mplayer. This will take about 3 MB of space. Install?", confirm=True)
if not result:
return
urllib.urlretrieve("http://mplayer.kenkon.net/files/mplayer-win32-mingw-dev-svn20061001.exe", "mplayerdl.exe")
os.system("mplayerdl.exe")
mpath = "C:\\Progra~2\\MPlayer\\mplayer.exe"
else:
mpath = "C:\\Progra~1\\MPlayer\\mplayer.exe"
else:
mpath = "C:\\Progra~2\\MPlayer\\mplayer.exe"
else:
mpath = "mplayer"
theorigfile = thefile
thefile = svlgui.SECURETEMPDIR+svlgui.sep+thefile.split(svlgui.sep)[-1].replace(" ","_").replace("-","_").split(".")[0]+'.wav'
print mpath+' -srate 48000 -vo null -vc null -ao pcm:fast:file="'+thefile+'" "'+theorigfile+'"'
if svlgui.PLATFORM=="win32":
os.system(mpath+' -srate 48000 -vo null -vc null -ao pcm:fast:file=\\"'+thefile+'\\" "'+theorigfile+'"')
else:
os.system(mpath+' -srate 48000 -vo null -vc null -ao pcm:fast:file="'+thefile+'" "'+theorigfile+'"')
if svlgui.PLATFORM=="osx": if svlgui.PLATFORM=="osx":
if not os.path.exists('sox/sox'): if not os.path.exists('sox/sox'):
try: try:
@ -679,6 +794,18 @@ def import_to_stage(widget=None):
os.system("""osascript -e 'do shell script "easy_install numpy" with administrator privileges'""") os.system("""osascript -e 'do shell script "easy_install numpy" with administrator privileges'""")
import numpy as NP import numpy as NP
SOX_EXEC = 'sox/sox' SOX_EXEC = 'sox/sox'
elif svlgui.PLATFORM=="win32":
SOX_EXEC = "C:\\Progra~2\\sox-14~1\\sox.exe"
if not os.path.exists(SOX_EXEC):
if os.path.exists("C:\\Progra~1\\sox-14~1\\sox.exe"):
SOX_EXEC = "C:\\Progra~1\\sox-14~1\\sox.exe"
else:
urllib.urlretrieve("http://downloads.sourceforge.net/project/sox/sox/14.4.0/sox-14.4.0-win32.exe?r=&ts=1358725954&use_mirror=iweb", 'sox.exe')
os.system("sox.exe")
import numpy as NP
elif "linux" in svlgui.PLATFORM:
import numpy as NP
SOX_EXEC = "sox"
svlgui.NP = NP svlgui.NP = NP
num_channels = 1 num_channels = 1
out_byps = 2 # Bytes per sample you want, must be 1, 2, 4, or 8 out_byps = 2 # Bytes per sample you want, must be 1, 2, 4, or 8
@ -692,8 +819,12 @@ def import_to_stage(widget=None):
data = NP.fromstring(subprocess.check_output(cmd),'<i%d'%(out_byps)) data = NP.fromstring(subprocess.check_output(cmd),'<i%d'%(out_byps))
data = data.reshape(len(data)/num_channels, num_channels) data = data.reshape(len(data)/num_channels, num_channels)
info = subprocess.check_output([SOX_EXEC,'--i',thefile]) info = subprocess.check_output([SOX_EXEC,'--i',thefile])
sound = svlgui.Sound(data, name=thefile.split('/')[-1], path=thefile, info=info) if i=="mp3":
sound = svlgui.Sound(data, name=thefile.split(svlgui.sep)[-1], path=theorigfile, info=info, type=i)
else:
sound = svlgui.Sound(data, name=thefile.split(svlgui.sep)[-1], path=thefile, info=info, type=i)
root.descendItem().add(sound) root.descendItem().add(sound)
break
MainWindow.stage.draw() MainWindow.stage.draw()
def import_to_library(widget=None): def import_to_library(widget=None):
@ -754,6 +885,39 @@ def redo(widget=None):
undo_stack.append(e) undo_stack.append(e)
MainWindow.stage.draw() MainWindow.stage.draw()
def cut(widget=None):
if MainWindow.scriptwindow.is_focused():
clip = MainWindow.scriptwindow.text[MainWindow.scriptwindow.selection[0]:MainWindow.scriptwindow.selection[1]]
MainWindow.scriptwindow.insert("")
svlgui.app.set_clipboard(clip)
def copy(widget=None):
if MainWindow.scriptwindow.is_focused():
clip = MainWindow.scriptwindow.text[MainWindow.scriptwindow.selection[0]:MainWindow.scriptwindow.selection[1]]
svlgui.app.set_clipboard(clip)
def paste(widget=None):
clip = svlgui.app.get_clipboard() if svlgui.app.query_clipboard() else None
if clip:
print clip
if MainWindow.stage.is_focused():
ctext = svlgui.Text(clip,200,100)
ctext.editing = False
# svlgui.CURRENTTEXT = self.ctext
ctext.onMouseDown = onMouseDownText
ctext.onMouseDrag = onMouseDragText
ctext.onMouseUp = onMouseUpText
self = root.descendItem()
self.add(ctext)
# 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.stage.draw()
elif MainWindow.scriptwindow.is_focused():
MainWindow.scriptwindow.insert(clip)
def add_keyframe(widget=None): def add_keyframe(widget=None):
print "af> ", root.descendItem().activeframe print "af> ", root.descendItem().activeframe
root.descendItem().add_frame(True) root.descendItem().add_frame(True)
@ -811,6 +975,29 @@ def convert_to_symbol(widget=None):
svlgui.ConvertToSymbolWindow(root, onMouseDownMC) svlgui.ConvertToSymbolWindow(root, onMouseDownMC)
MainWindow.stage.draw() MainWindow.stage.draw()
def export_svg(widget=None):
pass
def export_swf(widget=None):
global root
root.descendItem().activelayer.frames[root.descendItem().activelayer.currentframe].actions = MainWindow.scriptwindow.text
f = svlgui.file_dialog("save", name="untitled.swf")
if not f:
return
open(f.path+".sc",'w').write(create_sc(root))
# svlgui.execute("swfc/swfc_"+svlgui.PLATFORM+" "+os.getenv('HOME')+"/test.sc -o "+os.getenv('HOME')+"/test.swf")
x = os.system("swfc"+svlgui.sep+"swfc_"+svlgui.PLATFORM+" "+f.path+".sc -o "+f.path)
if sys.version_info < (2, 6):
if x==5: # which is the error value returned when linking libjpeg fails
if svlgui.alert("You appear to be missing libjpeg. Install it?", confirm=True):
os.system("""osascript -e 'do shell script "mkdir -p /usr/local/lib; cp swfc/libjpeg.8.dylib /usr/local/lib" with administrator privileges'""")
x = os.system("swfc/swfc_"+svlgui.PLATFORM+" "+f.path+".sc -o "+f.path)
if x==5:
svlgui.alert("Sorry, something has gone terribly wrong.")
else:
return
def about(widget=None): def about(widget=None):
svlgui.alert("Lightningbeam v1.0-alpha1\nLast Updated: "+update_date()+ svlgui.alert("Lightningbeam v1.0-alpha1\nLast Updated: "+update_date()+
"\nCreated by: Skyler Lehmkuhl\nBased on SWIFT") "\nCreated by: Skyler Lehmkuhl\nBased on SWIFT")
@ -830,9 +1017,9 @@ svlgui.menufuncs([["File",
["Edit", ["Edit",
("Undo", undo, "/z"), ("Undo", undo, "/z"),
("Redo", redo, "/^z"), ("Redo", redo, "/^z"),
"Cut", ("Cut", cut, "/x"),
"Copy", ("Copy", copy, "/c"),
"Paste", ("Paste", paste, "/v"),
"Delete", "Delete",
("Preferences",preferences,"")], ("Preferences",preferences,"")],
["Timeline", ["Timeline",
@ -844,10 +1031,11 @@ svlgui.menufuncs([["File",
("Import to Stage",import_to_stage,"/I"), ("Import to Stage",import_to_stage,"/I"),
("Import to Library",import_to_library)], ("Import to Library",import_to_library)],
["Export", ["Export",
"Export .swf", ("Export .swf",export_swf,""),
"Export HTML5", "Export HTML5",
"Export Native Application", "Export Native Application",
"Export .sc", "Export .sc",
("Export SVG",export_svg,""),
"Export Image", "Export Image",
"Export Video", "Export Video",
"Export .pdf", "Export .pdf",

View File

@ -231,7 +231,7 @@ class MainWindowOSX:
# self.toolbox.buttons[1][0]._int().enabled = False # self.toolbox.buttons[1][0]._int().enabled = False
self.toolbox.buttons[3][0]._int().enabled = False self.toolbox.buttons[3][0]._int().enabled = False
self.toolbox.buttons[4][0]._int().enabled = False self.toolbox.buttons[4][0]._int().enabled = False
self.scriptwindow = svlgui.TextView() self.scriptwindow = svlgui.TextView(code=True)
self.paintgroup = svlgui.RadioGroup("Draw straight", "Draw smooth", "Draw as inked") self.paintgroup = svlgui.RadioGroup("Draw straight", "Draw smooth", "Draw as inked")
def setmode(self): def setmode(self):
svlgui.PMODE = self.value svlgui.PMODE = self.value

View File

@ -96,8 +96,30 @@ def lastval(arr,index):
return i return i
def angle_to_point(point1, point2):
deltaX = point2.x-point1.x
deltaY = point2.y-point1.y
angleInDegrees = math.atan2(-deltaY, deltaX) * 180 / math.pi
if angleInDegrees<0: angleInDegrees = 360+angleInDegrees
return angleInDegrees
def sqr(x) :
return x * x
def dist2(v, w):
return sqr(v.x - w.x) + sqr(v.y - w.y)
def distToSegmentSquared(p, v, w):
l2 = dist2(v, w)
if l2 == 0:
return dist2(p, v)
t = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2
if t < 0:
return dist2(p, v)
if t > 1:
return dist2(p, w)
return dist2(p, svlgui.Point(x=(v.x+t*(w.x-v.x)), y=(v.y+t*(w.y-v.y))))
def distToSegment(p, v, w):
return math.sqrt(distToSegmentSquared(p, v, w))
def catmullRom2bezier( points ) : def catmullRom2bezier( points ) :
#crp = points.split(/[,\s]/); #crp = points.split(/[,\s]/);

View File

@ -14,6 +14,8 @@ import ez_setup
ez_setup.use_setuptools() ez_setup.use_setuptools()
import sys import sys
import shutil
import pygments
from setuptools import setup from setuptools import setup
@ -70,3 +72,11 @@ setup(
name="Lightningbeam", name="Lightningbeam",
**extra_options **extra_options
) )
if sys.platform == 'win32':
shutil.rmtree("dist\GUI")
shutil.rmtree("dist\pygments")
print "Copying PyGUI files..."
shutil.copytree("GUI", "dist\GUI")
print "Copying Pygments files..."
shutil.copytree("\\".join(pygments.__file__.split("\\")[:-1]), "dist\pygments")

255
svlgui.py
View File

@ -1,4 +1,4 @@
#! /usr/bin/python #! /usr/bin/python
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*-
# © 2012 Skyler Lehmkuhl # © 2012 Skyler Lehmkuhl
# Released under the GPLv3. For more information, see gpl.txt. # Released under the GPLv3. For more information, see gpl.txt.
@ -176,6 +176,8 @@ LINECOLOR = Color("#990099")
FILLCOLOR = Color("#00FF00") FILLCOLOR = Color("#00FF00")
TEXTCOLOR = Color("#000000") TEXTCOLOR = Color("#000000")
LINEWIDTH = 2
#Magic. Detect platform and select appropriate toolkit. To be used throughout code. #Magic. Detect platform and select appropriate toolkit. To be used throughout code.
if sys.platform=="linux2": if sys.platform=="linux2":
id = platform.machine() id = platform.machine()
@ -340,6 +342,9 @@ if SYSTEM=="osx":
m.new_cmd.enabled = 1 m.new_cmd.enabled = 1
m.undo_cmd.enabled = 1 m.undo_cmd.enabled = 1
m.redo_cmd.enabled = 1 m.redo_cmd.enabled = 1
m.copy_cmd.enabled = 1
m.cut_cmd.enabled = 1
m.paste_cmd.enabled = 1
m.run_file.enabled = 1 m.run_file.enabled = 1
m.run_html.enabled = 1 m.run_html.enabled = 1
m.create_sc.enabled = 1 m.create_sc.enabled = 1
@ -352,6 +357,7 @@ if SYSTEM=="osx":
m.send_to_back.enabled = 1 m.send_to_back.enabled = 1
m.import_to_stage.enabled = 1 m.import_to_stage.enabled = 1
m.import_to_library.enabled = 1 m.import_to_library.enabled = 1
m.export_swf.enabled = 1
m.convert_to_symbol.enabled = 1 m.convert_to_symbol.enabled = 1
m.preferences_cmd.enabled = 1 m.preferences_cmd.enabled = 1
@ -569,8 +575,8 @@ def menufuncs(j):
#menu = GUI.Menu("Test", [("Run", 'run_file')]) #menu = GUI.Menu("Test", [("Run", 'run_file')])
menus.append(menu) menus.append(menu)
else: else:
cmds={"New":"new_cmd", "Save":"save_cmd", "Save As":"save_as_cmd", "Open":"open_cmd","About Lightningbeam...":"about_cmd",\ cmds={"New...":"new_cmd", "Save":"save_cmd", "Save As":"save_as_cmd", "Open":"open_cmd","About Lightningbeam...":"about_cmd",\
"Preferences":"preferences_cmd", "Undo":"undo_cmd", "Redo":"redo_cmd"} "Preferences":"preferences_cmd", "Undo":"undo_cmd", "Redo":"redo_cmd", "Cut":"cut_cmd", "Copy":"copy_cmd", "Paste":"paste_cmd"}
[setattr(app,cmds[k[0]],k[1]) for k in i if (k[0] in cmds)] [setattr(app,cmds[k[0]],k[1]) for k in i if (k[0] in cmds)]
class VBox(Widget): class VBox(Widget):
@ -1183,6 +1189,9 @@ class Canvas(Widget):
self.canvas.invalidate_rect((0,0,self.canvas.extent[0],self.canvas.extent[1])) self.canvas.invalidate_rect((0,0,self.canvas.extent[0],self.canvas.extent[1]))
elif SYSTEM=="html": elif SYSTEM=="html":
jscommunicate("drawcanvas("+self.tid+")") jscommunicate("drawcanvas("+self.tid+")")
def is_focused(self):
if SYSTEM=="osx":
return self.canvas.is_target()
def add(self, obj, x, y): def add(self, obj, x, y):
obj.x = x obj.x = x
obj.y = y obj.y = y
@ -1209,8 +1218,15 @@ class TextView(Widget):
def _settext(self, text): def _settext(self, text):
if SYSTEM=="osx": if SYSTEM=="osx":
self.box.text = text self.box.text = text
def _getselection(self):
if SYSTEM=="osx":
return self.box.selection
def _setselection(self, tup):
if SYSTEM=="osx":
self.box.selection = tup
text = property(_gettext, _settext) text = property(_gettext, _settext)
def __init__(self,editable=True,width=False,height=False): selection = property(_getselection, _setselection)
def __init__(self,editable=True,width=False,height=False,code=False):
if SYSTEM=="gtk": if SYSTEM=="gtk":
self.sw=ScrolledWindow() self.sw=ScrolledWindow()
self.box=gtk.TextView() self.box=gtk.TextView()
@ -1228,8 +1244,10 @@ class TextView(Widget):
def mouse_down(self, event): def mouse_down(self, event):
self.become_target() self.become_target()
GUI.TextEditor.mouse_down(self, event) GUI.TextEditor.mouse_down(self, event)
# self.box = OSXTextEditor(scrolling="hv") if code:
self.box = CodeEditor() self.box = CodeEditor()
else:
self.box = OSXTextEditor(scrolling="hv")
self.box.font = Font("Courier", 12, []) self.box.font = Font("Courier", 12, [])
if width and height: if width and height:
self.box.size = (width, height) self.box.size = (width, height)
@ -1242,9 +1260,20 @@ class TextView(Widget):
return self.box return self.box
elif SYSTEM=="html": elif SYSTEM=="html":
return self.box return self.box
def is_focused(self):
if SYSTEM=="osx":
return self.box.is_target()
def insert(self, text):
if SYSTEM=="osx":
if isinstance(self.box, CodeEditor):
self.box.text = self.box.text[:self.box.selection[0]]+text+self.box.text[self.box.selection[1]:]
self.box.scursorpos = self.box.cursorpos = self.box.selection[0]+len(text)
self.box.selection = (self.box.selection[0]+len(text), self.box.selection[0]+len(text))
self.box.invalidate_rect([0,0,self.box.extent[0],self.box.extent[1]])
def scroll_bottom(self): def scroll_bottom(self):
if SYSTEM=="osx": if SYSTEM=="osx":
self.scroll_page_down(); self.scroll_page_down();
self.box.invalidate()
class TextEntry(Widget): class TextEntry(Widget):
def __init__(self,text="",password=False): def __init__(self,text="",password=False):
@ -1950,7 +1979,7 @@ class Text (object):
class Sound: class Sound:
"""Class for storing sounds in.""" """Class for storing sounds in."""
def __init__(self, data, name, path, info): def __init__(self, data, name, path, info, type):
global Library global Library
Library.append(self) Library.append(self)
self.data = data self.data = data
@ -1962,6 +1991,7 @@ class Sound:
self.yscale = 0 self.yscale = 0
self.path = path self.path = path
self.iname = None self.iname = None
self.type = type
reading_comments_flag = False reading_comments_flag = False
other = '' other = ''
for l in info.splitlines(): for l in info.splitlines():
@ -2017,7 +2047,7 @@ class Sound:
def hitTest(self, x, y): def hitTest(self, x, y):
return False return False
def print_sc(self): def print_sc(self):
retval = ".sound "+self.name+" \""+self.path+"\"\n" retval = ".sound "+self.name+" \""+self.path.replace("\\","\\\\")+"\"\n"
return retval return retval
def print_html(self): def print_html(self):
retval = "var "+self.name.replace(".","_")+" = new Sound();\n"+self.name.replace(".","_")+"._sound = new Audio('"+self.path.split("/")[-1]+"');\n" retval = "var "+self.name.replace(".","_")+" = new Sound();\n"+self.name.replace(".","_")+"._sound = new Audio('"+self.path.split("/")[-1]+"');\n"
@ -2520,6 +2550,9 @@ class Group (object):
self.tempgroup = None self.tempgroup = None
self.is_mc = False self.is_mc = False
self.name = "g"+str(int(random.random()*10000))+str(SITER) self.name = "g"+str(int(random.random()*10000))+str(SITER)
self.lines = []
self.fills = []
self.activepoint = None
if "onload" in kwargs: if "onload" in kwargs:
kwargs["onload"](self) kwargs["onload"](self)
def draw(self,cr=None,transform=None,rect=None): def draw(self,cr=None,transform=None,rect=None):
@ -2540,6 +2573,8 @@ class Group (object):
cr.pencolor = Color([0,0,1]).pygui cr.pencolor = Color([0,0,1]).pygui
cr.stroke_rect([sorted([self.startx,self.cx])[0], sorted([self.starty,self.cy])[0], \ cr.stroke_rect([sorted([self.startx,self.cx])[0], sorted([self.starty,self.cy])[0], \
sorted([self.startx,self.cx])[1], sorted([self.starty,self.cy])[1]]) sorted([self.startx,self.cx])[1], sorted([self.starty,self.cy])[1]])
for i in self.lines:
i.draw(cr, rect=rect)
def add(self, *args): def add(self, *args):
self.activelayer.add(*args) self.activelayer.add(*args)
def add_frame(self, populate): def add_frame(self, populate):
@ -2611,6 +2646,66 @@ class Group (object):
self.tempgroup = None self.tempgroup = None
self.activelayer.currentselect = None self.activelayer.currentselect = None
self.startx, self.starty = x, y self.startx, self.starty = x, y
if MODE in " s":
for i in self.lines:
if abs(x-i.endpoint1.x)<10 and abs(y-i.endpoint1.y)<10:
i.endpoint1.x = x
i.endpoint1.y = y
self.activepoint = i.endpoint1
return
elif abs(x-i.endpoint2.x)<10 and abs(y-i.endpoint2.y)<10:
i.endpoint2.x = x
i.endpoint2.y = y
self.activepoint = i.endpoint2
return
elif MODE=="b":
nlines = [i for i in self.lines]
endsleft = True
while endsleft:
endsleft = False
print nlines
for i in reversed(nlines):
if not (i.endpoint1 in [j.endpoint1 for j in nlines if not j==i]+[j.endpoint2 for j in nlines if not j==i]):
nlines.remove(i)
endsleft = True
elif not (i.endpoint2 in [j.endpoint1 for j in nlines if not j==i]+[j.endpoint2 for j in nlines if not j==i]):
nlines.remove(i)
endsleft = True
if nlines:
mindist = sys.maxint
point = Point(x, y)
closestsegment = None
for i in nlines:
d = misc_funcs.distToSegment(point,i.endpoint1,i.endpoint2)
if d<mindist:
mindist = d
closestsegment = i
if closestsegment:
# Then go to endpoint of closestsegment counterclockwise from point
angle1 = misc_funcs.angle_to_point(point, closestsegment.endpoint1)
angle2 = misc_funcs.angle_to_point(point, closestsegment.endpoint2)
if (angle1<angle2 and angle2-angle1<180):
startpoint = closestsegment.endpoint2
else:
startpoint = closestsegment.endpoint1
print startpoint.lines
linelist = [closestsegment]
# nextline = max([[closestsegment.angle(i),i] for i in startpoint.lines if not i in linelist])
# print nextline
# Then, follow clockwise-most segment leading off from said point
while True:
try:
nextline = max([[closestsegment.angle(i),i] for i in startpoint.lines if not i==closestsegment])[1]
except:
break
closestsegment = nextline
if not nextline in linelist:
linelist.append(nextline)
else:
break
print "*****",linelist
# Continue until closestsegment is reached. I _think_ this is inevitable.
self.selecting = True self.selecting = True
else: else:
self.onMouseDown(self, x, y, button=button, clicks=clicks) self.onMouseDown(self, x, y, button=button, clicks=clicks)
@ -2628,6 +2723,25 @@ class Group (object):
if self.activelayer.level and MODE in [" ", "s"]: if self.activelayer.level and MODE in [" ", "s"]:
if self.activelayer.currentselect: if self.activelayer.currentselect:
self.activelayer.currentselect._onMouseUp(x, y, button=button, clicks=clicks) self.activelayer.currentselect._onMouseUp(x, y, button=button, clicks=clicks)
elif self.activepoint:
for i in self.lines:
if abs(self.activepoint.x-i.endpoint1.x)<10 and abs(self.activepoint.y-i.endpoint1.y)<10:
try:
[j for j in self.lines if self.activepoint==j.endpoint1][0].assign(i.endpoint1, 1)
except IndexError:
try:
[j for j in self.lines if self.activepoint==j.endpoint2][0].assign(i.endpoint1, 2)
break
except IndexError: pass
if abs(self.activepoint.x-i.endpoint2.x)<10 and abs(self.activepoint.y-i.endpoint2.y)<10:
try:
[j for j in self.lines if self.activepoint==j.endpoint1][0].assign(i.endpoint2, 1)
except IndexError:
try:
[j for j in self.lines if self.activepoint==j.endpoint2][0].assign(i.endpoint2, 2)
break
except IndexError: pass
break
elif abs(self.startx-x)>4 or abs(self.starty-y)>4: elif abs(self.startx-x)>4 or abs(self.starty-y)>4:
objs = [] objs = []
for i in reversed(self.currentFrame()): for i in reversed(self.currentFrame()):
@ -2662,6 +2776,9 @@ class Group (object):
if self.activelayer.level and MODE in [" ", "s"]: if self.activelayer.level and MODE in [" ", "s"]:
if self.activelayer.currentselect: if self.activelayer.currentselect:
self.activelayer.currentselect._onMouseDrag(x, y, button=button) self.activelayer.currentselect._onMouseDrag(x, y, button=button)
elif self.activepoint:
self.activepoint.x = x
self.activepoint.y = y
else: else:
self.onMouseDrag(self, x, y, button=button) self.onMouseDrag(self, x, y, button=button)
def onMouseDrag(self, self1, x, y, button=1, clicks=1): def onMouseDrag(self, self1, x, y, button=1, clicks=1):
@ -2800,6 +2917,119 @@ class TemporaryGroup(Group):
elif key=="down_arrow": elif key=="down_arrow":
self1.y+=1 self1.y+=1
class Point(object):
"""represents an x,y point, might store other data in the future"""
def __init__(self, x, y):
super(Point, self).__init__()
self.x = x
self.y = y
self.lines = set()
def __repr__(self):
return "<Point x="+str(self.x)+" y="+str(self.y)+">"
class Line(object):
"""Use Lines to build Shapes while allowing paintbucketing."""
def __init__(self, endpoint1, endpoint2, connection1 = None, connection2 = None):
super(Line, self).__init__()
self.endpoint1 = endpoint1
self.endpoint2 = endpoint2
self.endpoint1.lines.add(self)
self.endpoint2.lines.add(self)
self.connection1 = connection1
self.connection2 = connection2
if self.connection1: self.connection1.lines.add(self)
if self.connection2: self.connection2.lines.add(self)
self.linecolor = LINECOLOR
self.linewidth = LINEWIDTH
def __repr__(self):
return "<Line (endpoint1=("+str(self.endpoint1.x)+","+str(self.endpoint1.y)+"),endpoint2=("+str(self.endpoint2.x)+","+str(self.endpoint2.y)+"))>"
def assign(self, point, which):
if which==1:
self.connection1 = point
self.connection1.lines.add(self)
elif which==2:
self.connection2 = point
self.connection2.lines.add(self)
def angle(self, other):
if self.endpoint1==other.endpoint1:
x1 = self.endpoint2.x-self.endpoint1.x
y1 = self.endpoint2.y-self.endpoint1.y
x2 = other.endpoint2.x-other.endpoint1.x
y2 = other.endpoint2.y-other.endpoint1.y
elif self.endpoint2==other.endpoint1:
x1 = self.endpoint1.x-self.endpoint2.x
y1 = self.endpoint1.y-self.endpoint2.y
x2 = other.endpoint2.x-other.endpoint1.x
y2 = other.endpoint2.y-other.endpoint1.y
elif self.endpoint1==other.endpoint2:
x1 = self.endpoint2.x-self.endpoint1.x
y1 = self.endpoint2.y-self.endpoint1.y
x2 = other.endpoint1.x-other.endpoint2.x
y2 = other.endpoint1.y-other.endpoint2.y
elif self.endpoint2==other.endpoint2:
x1 = self.endpoint1.x-self.endpoint2.x
y1 = self.endpoint1.y-self.endpoint2.y
x2 = other.endpoint1.x-other.endpoint2.x
y2 = other.endpoint1.y-other.endpoint2.y
dot = x1*x2+y1*y2
mag1 = math.sqrt(x1**2+y1**2)
mag2 = math.sqrt(x2**2+y2**2)
angle = math.acos(dot/(mag1*mag2))/math.pi*180
cz = x1*y2-y1*x2
if cz>0: angle=360-angle
return angle
def draw(self, cr=None, transform=None, rect=None):
if self.connection1:
self.endpoint1 = self.connection1
if self.connection2:
self.endpoint2 = self.connection2
if SYSTEM=="gtk":
cr.save()
cr.set_source(self.linecolor.cairo)
cr.set_line_width(max(self.linewidth,1))
cr.move_to(self.endpoint1.x,self.endpoint2.y)
cr.line_to(self.endpoint2.x,self.endpoint2.y)
cr.stroke()
cr.restore()
elif SYSTEM=="android":
global tb
tb+="cr.save()\n"
tb+="cr.lineWidth = "+str(max(self.linewidth,1))+"\n"
tb+="cr.moveTo("+str(self.endpoint1.x)+","+str(self.endpoint1.y)+")\n"
tb+="cr.lineTo("+str(self.endpoint2.x)+","+str(self.endpoint2.y)+")\n"
tb+="cr.stroke()\n"
tb+="cr.restore()\n"
elif SYSTEM=="osx":
if USING_GL:
cr.save()
glColor3f(1.0,0.0,0.0)
glBegin(GL_LINES)
cr.x, cr.y = (self.endpoint1.x, self.endpoint1.y)
glVertex2f(cr.x, -cr.y)
point = (self.endpoint2.x, self.endpoint2.y)
glVertex2f(point[0], -point[1]) # because OpenGL swaps y coords
cr.x, cr.y = point
glEnd()
cr.restore()
else:
cr.gsave()
cr.newpath()
cr.pencolor = self.linecolor.pygui
cr.pensize = max(self.linewidth,1)
cr.moveto(self.endpoint1.x, self.endpoint1.y)
cr.lineto(self.endpoint2.x,self.endpoint2.y)
cr.stroke()
cr.grestore()
elif SYSTEM=="html":
tb = ""
tb+="cr.save()\n"
tb+="cr.lineWidth = "+str(max(self.linewidth,1))+"\n"
tb+="cr.moveTo("+str(self.endpoint1.x)+","+str(self.endpoint1.y)+")\n"
tb+="cr.lineTo("+str(self.endpoint2.x)+","+str(self.endpoint2.y)+")\n"
tb+="cr.stroke()\n"
tb+="cr.restore()\n"
jscommunicate(tb)
def set_cursor(curs, widget=None): def set_cursor(curs, widget=None):
if SYSTEM == "osx": if SYSTEM == "osx":
@ -2888,6 +3118,14 @@ def file_dialog(mode="open",default=None,types=None,multiple=False,name=None):
for i in types: for i in types:
ntypes.append(GUI.Files.FileType()) ntypes.append(GUI.Files.FileType())
ntypes[-1].suffix = i ntypes[-1].suffix = i
image = ["jpg", "jpeg", "png", "tiff", "tga"]
audio = ["wav", "mp3", "ogg"]
if i in image:
ntypes[-1].name = i.upper()+" Images"
elif i in audio:
ntypes[-1].name = i.upper()+" Audio"
else:
ntypes[-1].name = i.upper()+" Files"
if i in mactypes: if i in mactypes:
ntypes[-1].mac_type=mactypes[i] ntypes[-1].mac_type=mactypes[i]
types = ntypes types = ntypes
@ -2901,7 +3139,8 @@ def file_dialog(mode="open",default=None,types=None,multiple=False,name=None):
def execute(command): def execute(command):
rv = os.system(command.replace("/",sep)) rv = os.system(command.replace("/",sep))
if PLATFORM == "osx": print command.replace("/",sep)
if SYSTEM == "osx":
if rv==0: if rv==0:
return True return True
else: else: