Merge branch 'master' of github.com:skykooler/Lightningbeam
This commit is contained in:
commit
605d1a4c46
|
|
@ -42,7 +42,8 @@ class Canvas(Properties):
|
|||
self.textcolor = c
|
||||
|
||||
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)
|
||||
|
||||
def rlineto(self, dx, dy):
|
||||
|
|
|
|||
|
|
@ -171,10 +171,9 @@ class Canvas(GCanvas, GCanvasPaths):
|
|||
#ctx.set_source_rgba(*self._state.fillcolor._rgba)
|
||||
if self.fillcolor.image:
|
||||
# surface =
|
||||
ctx.set_source_pixbuf(self.fillcolor.image, 0, 0)
|
||||
ctx.save()
|
||||
print (self.maxx-self.minx)*1.0/self.fillcolor.image.get_width()
|
||||
self._gtk_ctx.scale((self.maxx-self.minx)*1.0/self.fillcolor.image.get_width(), 1)
|
||||
ctx.scale((self.maxx-self.minx)*1.0/self.fillcolor.image.get_width(), (self.maxy-self.miny)*1.0/self.fillcolor.image.get_height())
|
||||
ctx.set_source_pixbuf(self.fillcolor.image, 0, 0)
|
||||
ctx.fill_preserve()
|
||||
ctx.restore()
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#--------------------------------------------------------------------
|
||||
|
||||
from math import sin, cos, pi
|
||||
import sys
|
||||
import win32con as wc, win32ui as ui, win32gui as gui
|
||||
from win32con import PS_SOLID, BS_SOLID, RGN_AND
|
||||
#from win32ui import CreatePen, CreateBrush
|
||||
|
|
@ -119,6 +120,10 @@ class Canvas(GCanvas):
|
|||
def set_fillcolor(self, c):
|
||||
state = self._state
|
||||
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)
|
||||
|
||||
def get_textcolor(self):
|
||||
|
|
@ -156,19 +161,41 @@ class Canvas(GCanvas):
|
|||
|
||||
def newpath(self):
|
||||
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):
|
||||
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._win_path.StartFigure()
|
||||
|
||||
def lineto(self, x, y):
|
||||
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._current_point = (x, y)
|
||||
|
||||
def curveto(self, p1, p2, p3):
|
||||
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._current_point = p3
|
||||
|
||||
|
|
@ -182,6 +209,12 @@ class Canvas(GCanvas):
|
|||
self._current_point = None
|
||||
|
||||
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)
|
||||
|
||||
def stroke(self):
|
||||
|
|
|
|||
|
|
@ -7,8 +7,12 @@
|
|||
import win32con as wc, win32api as api
|
||||
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.image = image
|
||||
if image:
|
||||
color.image = im._win_image
|
||||
else:
|
||||
color._red = red
|
||||
color._green = green
|
||||
color._blue = blue
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
||||
def __init__(self, family, size, style):
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
|
||||
|
||||
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
|
||||
2. Copy the GUI folder from the root directory into dist\.
|
||||
3. The executable is in dist\lightningbeam.exe. You probably do need most of the DLL's, I haven't
|
||||
4. The executable is in dist\lightningbeam.exe. You probably do need most of the DLL's, I haven't
|
||||
gone through them yet.
|
||||
|
||||
Building on Ubuntu/Debian:
|
||||
|
|
|
|||
|
|
@ -83,12 +83,13 @@ class PyGUIFormatter(Formatter):
|
|||
class CodeEditor(ScrollableView):
|
||||
def __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.selecting = False
|
||||
self.lexer = ActionScriptLexer()
|
||||
self.cursorpos = 0
|
||||
self.scursorpos = 0
|
||||
self.selection = (0,0)
|
||||
self.formatter = PyGUIFormatter()
|
||||
# self.filter = NameHighlightFilter(
|
||||
self.filter = EverythingHighlightFilter(
|
||||
|
|
@ -169,6 +170,7 @@ class CodeEditor(ScrollableView):
|
|||
except:
|
||||
pass
|
||||
self.scursorpos = self.cursorpos
|
||||
self.selection = (self.cursorpos, self.cursorpos)
|
||||
if int(y/self.font.height):
|
||||
self.cursorpos+=1
|
||||
self.invalidate_rect([0,0,self.extent[0],self.extent[1]])
|
||||
|
|
@ -183,6 +185,7 @@ class CodeEditor(ScrollableView):
|
|||
pass
|
||||
if int(y/self.font.height):
|
||||
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]])
|
||||
def key_down(self, event):
|
||||
keydict = {127:"backspace",63272:"delete",63232:"up_arrow",63233:"down_arrow",
|
||||
|
|
@ -241,6 +244,8 @@ class CodeEditor(ScrollableView):
|
|||
else:
|
||||
self.text=self.text[:self.cursorpos]+str(key)+self.text[self.cursorpos:]
|
||||
self.cursorpos += 1
|
||||
self.scursorpos = self.cursorpos
|
||||
self.selection = (self.cursorpos, self.cursorpos)
|
||||
self.invalidate_rect([0,0,self.extent[0],self.extent[1]])
|
||||
class test(Application):
|
||||
def __init__(self):
|
||||
|
|
|
|||
238
lightningbeam.py
238
lightningbeam.py
|
|
@ -49,6 +49,8 @@ global undo_stack
|
|||
global redo_stack
|
||||
undo_stack = []
|
||||
redo_stack = []
|
||||
global preferences
|
||||
preferences={}
|
||||
|
||||
def clear(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 self.hitTest(x, y):
|
||||
self.clicked = True
|
||||
|
||||
elif svlgui.MODE in ["r", "e", "p"]:
|
||||
if svlgui.MODE=="r":
|
||||
# 'c' stands for 'current'
|
||||
|
|
@ -115,7 +118,19 @@ def onMouseDownGroup(self, x, y,button=1,clicks=1):
|
|||
elif svlgui.MODE=="e":
|
||||
self.cshape = ellipse(x, y, 0, 0)
|
||||
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.initx,self.cshape.inity = x, y
|
||||
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})
|
||||
clear(redo_stack)
|
||||
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)
|
||||
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
|
||||
MainWindow.stage.draw()
|
||||
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
|
||||
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])
|
||||
# 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):
|
||||
if svlgui.MODE==" ":
|
||||
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):
|
||||
global root
|
||||
print "RUNNING"
|
||||
print svlgui.FILE.name
|
||||
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")
|
||||
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 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+" "+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:
|
||||
svlgui.alert("Sorry, something has gone terribly wrong.")
|
||||
else:
|
||||
|
|
@ -340,14 +370,42 @@ def run_file(self=None):
|
|||
#TODO: Make this cross-platform compatible
|
||||
if svlgui.PLATFORM=="win32":
|
||||
# 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:
|
||||
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"):
|
||||
# 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'):
|
||||
|
|
@ -399,21 +457,31 @@ def run_file(self=None):
|
|||
outputtext.scroll_bottom() # this doesn't work
|
||||
except:
|
||||
pass
|
||||
return True
|
||||
if hasattr(svlgui, 'gobject'):
|
||||
svlgui.gobject.timeout_add(20, updatetrace, outputtext)
|
||||
else:
|
||||
r = misc_funcs.RepeatTimer(0.02, updatetrace, args=[outputtext])
|
||||
print dir(outputwin.window)
|
||||
r.daemon = True
|
||||
r.start()
|
||||
if svlgui.PLATFORM=="osx":
|
||||
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:
|
||||
svlgui.alert("Oops! Didn't work. I probably couldn't find your Flash debugger!")
|
||||
elif svlgui.PLATFORM=='win32':
|
||||
win_flash_player_loc = ""
|
||||
svlgui.execute('start '+win_flash_player_loc+" test.swf")
|
||||
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+" "+svlgui.FILE.name+".swf")
|
||||
elif svlgui.PLATFORM.startswith('linux'):
|
||||
linux_flash_player_loc = ""
|
||||
svlgui.execute("xdg-open "+linux_flash_player_loc+" "+os.getenv('HOME')+"/test.swf")
|
||||
linux_flash_player_loc = "/usr/bin/flashplayerdebugger"
|
||||
# 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):
|
||||
retval = "<head>\n\
|
||||
<style type=\"text/css\">\n\
|
||||
|
|
@ -539,7 +607,11 @@ def open_file(widget=None):
|
|||
global root
|
||||
MainWindow.stage.delete(root)
|
||||
shutil.rmtree(svlgui.SECURETEMPDIR)
|
||||
try:
|
||||
thetarfile = tarfile.open(fileobj=svlgui.file_dialog("open").open("rb"),mode="r:gz")
|
||||
except AttributeError:
|
||||
# User cancelled
|
||||
return
|
||||
basefile = thetarfile.extractfile("basefile")
|
||||
root, svlgui.Library = pickle.load(basefile)
|
||||
svlgui.SECURETEMPDIR = tempfile.mkdtemp()
|
||||
|
|
@ -566,8 +638,11 @@ def save_file(widget=None):
|
|||
tarinfo = tarfile.TarInfo('basefile')
|
||||
tarinfo.size = len(data)
|
||||
if svlgui.FILE.name.startswith(svlgui.TEMPDIR):
|
||||
try:
|
||||
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:
|
||||
thetarfile = tarfile.open(svlgui.FILE.name,mode="w:gz")
|
||||
thetarfile.addfile(tarinfo, StringIO.StringIO(data))
|
||||
|
|
@ -607,7 +682,11 @@ def save_file_as(widget=None):
|
|||
data = pickle.dumps((root,svlgui.Library))
|
||||
tarinfo = tarfile.TarInfo('basefile')
|
||||
tarinfo.size = len(data)
|
||||
try:
|
||||
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))
|
||||
#Save the path so we can come back here
|
||||
lastpath = os.path.abspath(".")
|
||||
|
|
@ -629,7 +708,11 @@ def save_file_as(widget=None):
|
|||
svlgui.FILE = thetarfile
|
||||
pass
|
||||
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"):
|
||||
if thefile.endswith(i):
|
||||
# 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")
|
||||
elif "linux" in svlgui.PLATFORM:
|
||||
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))
|
||||
print im.filled
|
||||
im.onMouseDown = onMouseDownObj
|
||||
im.onMouseMove = onMouseMoveObj
|
||||
im.onMouseDrag = onMouseDragObj
|
||||
|
|
@ -649,7 +740,31 @@ def import_to_stage(widget=None):
|
|||
root.descendItem().add(im)
|
||||
break
|
||||
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 not os.path.exists('sox/sox'):
|
||||
try:
|
||||
|
|
@ -679,6 +794,18 @@ def import_to_stage(widget=None):
|
|||
os.system("""osascript -e 'do shell script "easy_install numpy" with administrator privileges'""")
|
||||
import numpy as NP
|
||||
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
|
||||
num_channels = 1
|
||||
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 = data.reshape(len(data)/num_channels, num_channels)
|
||||
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)
|
||||
break
|
||||
|
||||
MainWindow.stage.draw()
|
||||
def import_to_library(widget=None):
|
||||
|
|
@ -754,6 +885,39 @@ def redo(widget=None):
|
|||
undo_stack.append(e)
|
||||
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):
|
||||
print "af> ", root.descendItem().activeframe
|
||||
root.descendItem().add_frame(True)
|
||||
|
|
@ -811,6 +975,29 @@ def convert_to_symbol(widget=None):
|
|||
svlgui.ConvertToSymbolWindow(root, onMouseDownMC)
|
||||
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):
|
||||
svlgui.alert("Lightningbeam v1.0-alpha1\nLast Updated: "+update_date()+
|
||||
"\nCreated by: Skyler Lehmkuhl\nBased on SWIFT")
|
||||
|
|
@ -830,9 +1017,9 @@ svlgui.menufuncs([["File",
|
|||
["Edit",
|
||||
("Undo", undo, "/z"),
|
||||
("Redo", redo, "/^z"),
|
||||
"Cut",
|
||||
"Copy",
|
||||
"Paste",
|
||||
("Cut", cut, "/x"),
|
||||
("Copy", copy, "/c"),
|
||||
("Paste", paste, "/v"),
|
||||
"Delete",
|
||||
("Preferences",preferences,"")],
|
||||
["Timeline",
|
||||
|
|
@ -844,10 +1031,11 @@ svlgui.menufuncs([["File",
|
|||
("Import to Stage",import_to_stage,"/I"),
|
||||
("Import to Library",import_to_library)],
|
||||
["Export",
|
||||
"Export .swf",
|
||||
("Export .swf",export_swf,""),
|
||||
"Export HTML5",
|
||||
"Export Native Application",
|
||||
"Export .sc",
|
||||
("Export SVG",export_svg,""),
|
||||
"Export Image",
|
||||
"Export Video",
|
||||
"Export .pdf",
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ class MainWindowOSX:
|
|||
# self.toolbox.buttons[1][0]._int().enabled = False
|
||||
self.toolbox.buttons[3][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")
|
||||
def setmode(self):
|
||||
svlgui.PMODE = self.value
|
||||
|
|
|
|||
|
|
@ -96,8 +96,30 @@ def lastval(arr,index):
|
|||
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 ) :
|
||||
#crp = points.split(/[,\s]/);
|
||||
|
|
|
|||
10
setup.py
10
setup.py
|
|
@ -14,6 +14,8 @@ import ez_setup
|
|||
ez_setup.use_setuptools()
|
||||
|
||||
import sys
|
||||
import shutil
|
||||
import pygments
|
||||
from setuptools import setup
|
||||
|
||||
|
||||
|
|
@ -70,3 +72,11 @@ setup(
|
|||
name="Lightningbeam",
|
||||
**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
255
svlgui.py
|
|
@ -1,4 +1,4 @@
|
|||
#! /usr/bin/python
|
||||
#! /usr/bin/python
|
||||
# -*- coding:utf-8 -*-
|
||||
# © 2012 Skyler Lehmkuhl
|
||||
# Released under the GPLv3. For more information, see gpl.txt.
|
||||
|
|
@ -176,6 +176,8 @@ LINECOLOR = Color("#990099")
|
|||
FILLCOLOR = Color("#00FF00")
|
||||
TEXTCOLOR = Color("#000000")
|
||||
|
||||
LINEWIDTH = 2
|
||||
|
||||
#Magic. Detect platform and select appropriate toolkit. To be used throughout code.
|
||||
if sys.platform=="linux2":
|
||||
id = platform.machine()
|
||||
|
|
@ -340,6 +342,9 @@ if SYSTEM=="osx":
|
|||
m.new_cmd.enabled = 1
|
||||
m.undo_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_html.enabled = 1
|
||||
m.create_sc.enabled = 1
|
||||
|
|
@ -352,6 +357,7 @@ if SYSTEM=="osx":
|
|||
m.send_to_back.enabled = 1
|
||||
m.import_to_stage.enabled = 1
|
||||
m.import_to_library.enabled = 1
|
||||
m.export_swf.enabled = 1
|
||||
m.convert_to_symbol.enabled = 1
|
||||
m.preferences_cmd.enabled = 1
|
||||
|
||||
|
|
@ -569,8 +575,8 @@ def menufuncs(j):
|
|||
#menu = GUI.Menu("Test", [("Run", 'run_file')])
|
||||
menus.append(menu)
|
||||
else:
|
||||
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"}
|
||||
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", "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)]
|
||||
|
||||
class VBox(Widget):
|
||||
|
|
@ -1183,6 +1189,9 @@ class Canvas(Widget):
|
|||
self.canvas.invalidate_rect((0,0,self.canvas.extent[0],self.canvas.extent[1]))
|
||||
elif SYSTEM=="html":
|
||||
jscommunicate("drawcanvas("+self.tid+")")
|
||||
def is_focused(self):
|
||||
if SYSTEM=="osx":
|
||||
return self.canvas.is_target()
|
||||
def add(self, obj, x, y):
|
||||
obj.x = x
|
||||
obj.y = y
|
||||
|
|
@ -1209,8 +1218,15 @@ class TextView(Widget):
|
|||
def _settext(self, text):
|
||||
if SYSTEM=="osx":
|
||||
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)
|
||||
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":
|
||||
self.sw=ScrolledWindow()
|
||||
self.box=gtk.TextView()
|
||||
|
|
@ -1228,8 +1244,10 @@ class TextView(Widget):
|
|||
def mouse_down(self, event):
|
||||
self.become_target()
|
||||
GUI.TextEditor.mouse_down(self, event)
|
||||
# self.box = OSXTextEditor(scrolling="hv")
|
||||
if code:
|
||||
self.box = CodeEditor()
|
||||
else:
|
||||
self.box = OSXTextEditor(scrolling="hv")
|
||||
self.box.font = Font("Courier", 12, [])
|
||||
if width and height:
|
||||
self.box.size = (width, height)
|
||||
|
|
@ -1242,9 +1260,20 @@ class TextView(Widget):
|
|||
return self.box
|
||||
elif SYSTEM=="html":
|
||||
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):
|
||||
if SYSTEM=="osx":
|
||||
self.scroll_page_down();
|
||||
self.box.invalidate()
|
||||
|
||||
class TextEntry(Widget):
|
||||
def __init__(self,text="",password=False):
|
||||
|
|
@ -1950,7 +1979,7 @@ class Text (object):
|
|||
|
||||
class Sound:
|
||||
"""Class for storing sounds in."""
|
||||
def __init__(self, data, name, path, info):
|
||||
def __init__(self, data, name, path, info, type):
|
||||
global Library
|
||||
Library.append(self)
|
||||
self.data = data
|
||||
|
|
@ -1962,6 +1991,7 @@ class Sound:
|
|||
self.yscale = 0
|
||||
self.path = path
|
||||
self.iname = None
|
||||
self.type = type
|
||||
reading_comments_flag = False
|
||||
other = ''
|
||||
for l in info.splitlines():
|
||||
|
|
@ -2017,7 +2047,7 @@ class Sound:
|
|||
def hitTest(self, x, y):
|
||||
return False
|
||||
def print_sc(self):
|
||||
retval = ".sound "+self.name+" \""+self.path+"\"\n"
|
||||
retval = ".sound "+self.name+" \""+self.path.replace("\\","\\\\")+"\"\n"
|
||||
return retval
|
||||
def print_html(self):
|
||||
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.is_mc = False
|
||||
self.name = "g"+str(int(random.random()*10000))+str(SITER)
|
||||
self.lines = []
|
||||
self.fills = []
|
||||
self.activepoint = None
|
||||
if "onload" in kwargs:
|
||||
kwargs["onload"](self)
|
||||
def draw(self,cr=None,transform=None,rect=None):
|
||||
|
|
@ -2540,6 +2573,8 @@ class Group (object):
|
|||
cr.pencolor = Color([0,0,1]).pygui
|
||||
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]])
|
||||
for i in self.lines:
|
||||
i.draw(cr, rect=rect)
|
||||
def add(self, *args):
|
||||
self.activelayer.add(*args)
|
||||
def add_frame(self, populate):
|
||||
|
|
@ -2611,6 +2646,66 @@ class Group (object):
|
|||
self.tempgroup = None
|
||||
self.activelayer.currentselect = None
|
||||
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
|
||||
else:
|
||||
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.currentselect:
|
||||
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:
|
||||
objs = []
|
||||
for i in reversed(self.currentFrame()):
|
||||
|
|
@ -2662,6 +2776,9 @@ class Group (object):
|
|||
if self.activelayer.level and MODE in [" ", "s"]:
|
||||
if self.activelayer.currentselect:
|
||||
self.activelayer.currentselect._onMouseDrag(x, y, button=button)
|
||||
elif self.activepoint:
|
||||
self.activepoint.x = x
|
||||
self.activepoint.y = y
|
||||
else:
|
||||
self.onMouseDrag(self, x, y, button=button)
|
||||
def onMouseDrag(self, self1, x, y, button=1, clicks=1):
|
||||
|
|
@ -2800,6 +2917,119 @@ class TemporaryGroup(Group):
|
|||
elif key=="down_arrow":
|
||||
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):
|
||||
if SYSTEM == "osx":
|
||||
|
|
@ -2888,6 +3118,14 @@ def file_dialog(mode="open",default=None,types=None,multiple=False,name=None):
|
|||
for i in types:
|
||||
ntypes.append(GUI.Files.FileType())
|
||||
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:
|
||||
ntypes[-1].mac_type=mactypes[i]
|
||||
types = ntypes
|
||||
|
|
@ -2901,7 +3139,8 @@ def file_dialog(mode="open",default=None,types=None,multiple=False,name=None):
|
|||
|
||||
def execute(command):
|
||||
rv = os.system(command.replace("/",sep))
|
||||
if PLATFORM == "osx":
|
||||
print command.replace("/",sep)
|
||||
if SYSTEM == "osx":
|
||||
if rv==0:
|
||||
return True
|
||||
else:
|
||||
|
|
|
|||
Loading…
Reference in New Issue