Lightningbeam/svlgui.py

3314 lines
107 KiB
Python

#! /usr/bin/python
# -*- coding:utf-8 -*-
# © 2012 Skyler Lehmkuhl
# Released under the GPLv3. For more information, see gpl.txt.
import os
import sys
import math
import random
import colors
import platform
import re
import shutil
import traceback
try:
from PIL import Image as PILimage
GLEnablable = True
except ImportError:
GLEnablable = False
'''
# Tool mode. Keyboard shortcut is the same key. Modes are:
# " ": selection
# "l": lasso tool
# "s": scale/rotate tool
# "t": text tool
# "r": rectangle tool
# "e": ellipse tool
# "c": curve tool
# "p": paintbrush tool
# "n": pen tool
# "b": paint bucket tool
'''
MODE=" "
#Painbrush mode
PMODE = "Draw straight"
SITER=0
#Currentframe - the frame selected on the timeline. Not necessarily the frame being shown.
CURRENTFRAME=0
#Framerate - speed at which animation is played back
FRAMERATE=50
#Width and height are the width and height of the document
WIDTH, HEIGHT = 500, 500
#Whether we are using OpenGL for rendering. Currently we need PIL for this.
if GLEnablable:
try:
import OpenGL
USING_GL = True
except ImportError:
USING_GL = False
# Disable OpenGL. It's not ready for prime time.
USING_GL = False
#Object which has the keyboard focus.
FOCUS = None
#Options for export
EXPORT_OPTS = {"swf":False,"html5":False,"basehtml":False,"fallback":False,"pack":False}
#Editing - whether the user is editing text
EDITING = True
CURRENTTEXT = None
#Scaling - whether the user is resizing an object
SCALING = False
#Library. Contatins all objects whether displayed or not.
Library = []
class Color (object):
def __getstate__(self):
dict = self.__dict__.copy()
print dict
dict['image'] = None
return dict
def __init__(self, val):
if type(val)==type([]):
self.type = "RGB"
self.val = val
elif isinstance(val, basestring):
if val.startswith("#"):
self.type = "RGB"
self.val = hex2rgb(val)
else:
global Library
Library.append(self)
self.type = "Image"
self.val = val
self.set_image(val)
def _getcairo(self):
if self.type=="RGB":
return cairo.SolidPattern(*self.val)
elif self.type=="Image":
surface = cairo.ImageSurface.create_from_png(self.val)
pat = cairo.SurfacePattern(surface)
return pat
def _getpygui(self):
if self.type=="RGB":
return Colors.rgb(*self.val)
elif self.type=="Image":
a = Colors.rgb(0,0,0,1,image=True,im=self.image)
return a
def _getrgb(self):
if self.type=="RGB":
return rgb2hex(*self.val)
else:
print "Error: Trying to get RGB from image!"
return None
def _setrgb(self, rgb):
self.type = "RGB"
if (val)==type([]):
self.val = rgb
elif type(val)==type(""):
self.val = hex2rgb(val)
cairo = property(_getcairo)
pygui = property(_getpygui)
rgb = property(_getrgb, _setrgb)
def set_image(self, path):
if SYSTEM=="osx":
self.image = GUI.Image(file=path)
def print_sc(self):
retval = ".png "+self.val.split('/')[-1].replace(' ','_').replace('.','_')+" \""+self.val+"\"\n"
return retval
def print_html(self):
shutil.copy(self.val, os.getenv('HOME')+"/"+self.val.split('/')[-1])
retval = "var "+self.val.split('/')[-1].replace(' ','_').replace('.','_')+" = new Image();\n"
retval = retval+self.val.split('/')[-1].replace(' ','_').replace('.','_')+".src = \""+self.val.split("/")[-1]+"\";\n"
return retval
def rgb2hex(r, g, b, a=1):
r=hex(int(r*255)).split("x")[1].zfill(2)
g=hex(int(g*255)).split("x")[1].zfill(2)
b=hex(int(b*255)).split("x")[1].zfill(2)
a=hex(int(a*255)).split("x")[1].zfill(2)
return "#"+r+g+b+a
def hex2rgb(hex):
a=hex[1]
b=hex[2]
c=hex[3]
if len(hex)==7:
d=hex[4]
e=hex[5]
f=hex[6]
ab = a+b
cd = c+d
ef = e+f
return (int(ab, 16)/256.0, int(cd, 16)/256.0, int(ef, 16)/256.0)
elif len(hex)==9:
d=hex[4]
e=hex[5]
f=hex[6]
g=hex[7]
h=hex[8]
ab = a+b
cd = c+d
ef = e+f
gh = g+h
return (int(ab, 16)/256.0, int(cd, 16)/256.0, int(ef, 16)/256.0, int(gh, 16)/256.0)
else:
return (int(a, 16)/16.0, int(b, 16)/16.0, int(c, 16)/16.0)
LINECOLOR = Color("#990099")
FILLCOLOR = Color("#00FF00")
TEXTCOLOR = Color("#000000")
#Magic. Detect platform and select appropriate toolkit. To be used throughout code.
if sys.platform=="linux2":
id = platform.machine()
if id.startswith('arm'):
PLATFORM = 'linuxARM'
elif (not id) or (not re.match('(x|i[3-6])86$', id) is None):
PLATFORM = 'linux32'
elif id.lower() in ('x86_64', "amd64"):
PLATFORM = 'linux64'
elif "ppc" in plid.lower():
PLATFORM = "linuxPPC"
else:
PLATFORM = "error"
import gtk
import cairo
import gobject
import Image
import time
import misc_funcs
#SYSTEM="gtk"
### TESTING - gtk should be Linux platform, at least for now ####
#'''
import pickle
import tarfile
import tempfile
import GUI # Using PyGUI. Experimental.
from GUI import Window as OSXWindow, Button as OSXButton, Image as OSXImage
from GUI import Frame as OSXFrame, Color as OSXColor, Grid as OSXGrid, CheckBox as OSXCheckBox
from GUI import Label as OSXLabel, RadioGroup as OSXRadioGroup, RadioButton as OSXRadioButton
from GUI import Column, Row, ScrollableView, TextEditor, Colors, ModalDialog
from GUI import StdCursors, Alerts, FileDialogs, Font, TextField, Slider
from GUI.StdMenus import basic_menus, file_cmds, print_cmds
from GUI.StdButtons import DefaultButton, CancelButton
from GUI.Files import FileType
if USING_GL:
from OpenGL.GL import *
from OpenGL.GLU import *
from GUI import GL
try:
from PIL import Image as PILImage
except ImportError:
import Image as PILImage
from GUI.Geometry import offset_rect, rect_sized
#If we can import this, we are in the install directory. Mangle media paths accordingly.
try:
from distpath import media_path
except:
media_path = ""
#app = GUI.application()
SYSTEM="osx"
TEMPDIR = "/tmp"
FONT = u'Times New Roman'
'''
SYSTEM="html"
ids = {}
jsdefs = []
jsfunctions = ""'''
sep = "/"
elif sys.platform=="win32":
PLATFORM="win32"
import pickle
import tarfile
import tempfile
import misc_funcs
import GUI # Using PyGUI. Experimental.
from GUI import Window as OSXWindow, Button as OSXButton, Image as OSXImage
from GUI import Frame as OSXFrame, Color as OSXColor, Grid as OSXGrid, CheckBox as OSXCheckBox
from GUI import Label as OSXLabel, RadioGroup as OSXRadioGroup, RadioButton as OSXRadioButton
from GUI import Column, Row, ScrollableView, TextEditor, Colors, ModalDialog
from GUI import StdCursors, Alerts, FileDialogs, Font, TextField, Slider
from GUI.StdMenus import basic_menus, file_cmds, print_cmds
from GUI.StdButtons import DefaultButton, CancelButton
from GUI.Files import FileType
from GUI.Geometry import offset_rect, rect_sized
if USING_GL:
from OpenGL.GL import *
from OpenGL.GLU import *
from GUI import GL
try:
from PIL import Image as PILImage
except ImportError:
import Image as PILImage
media_path = ""
SYSTEM="osx"
TEMPDIR="C:\\Windows\\Temp"
sep = "\\"
elif sys.platform=="linux-armv6l":
import android
import tarfile
import tempfile
droid = android.Android()
SYSTEM="android"
TEMPDIR="/tmp" # TODO:FIXTHIS
media_path = ""
tb = ""
sep = "/"
print str(sys.platform)
elif sys.platform=="darwin":
PLATFORM="osx"
import pickle
import misc_funcs
import tarfile
import tempfile
#'''
import GUI # Using PyGUI. Experimental.
from GUI import Window as OSXWindow, Button as OSXButton, Image as OSXImage
from GUI import Frame as OSXFrame, Color as OSXColor, Grid as OSXGrid, CheckBox as OSXCheckBox
from GUI import Label as OSXLabel, RadioGroup as OSXRadioGroup, RadioButton as OSXRadioButton
from GUI import Column, Row, ScrollableView, TextEditor, Colors, ModalDialog
from GUI import StdCursors, Alerts, FileDialogs, Font, TextField, Slider
from GUI.StdMenus import basic_menus, file_cmds, print_cmds
from GUI.StdButtons import DefaultButton, CancelButton
from GUI.Files import FileType
from GUI.Geometry import offset_rect, rect_sized
if USING_GL:
from OpenGL.GL import *
from OpenGL.GLU import *
from GUI import GL
try:
from PIL import Image as PILImage
except ImportError:
import Image as PILImage
SYSTEM="osx"
'''
import pyglet # Using Pyglet. Even more experimental. As in doesn't work yet.
SYSTEM="pyglet"
''' # comment these out to use pyglet
import Cocoa
SYSTEM_FONTS = list(Cocoa.NSFontManager.sharedFontManager().availableFontFamilies())
FONT_PATH = "/Library/Fonts/"
FONT = u'Times New Roman'
media_path = ""
#app = GUI.application()
SYSTEM="osx"
TEMPDIR="/tmp"
sep = "/"
if SYSTEM=="osx":
from codeeditor import CodeEditor
FILE = tarfile.open(name=TEMPDIR+"/Untitled",mode="w:gz")
FILE.close()
#Used for storing images, sounds, etc.
SECURETEMPDIR = tempfile.mkdtemp()
__windowlist__=[]
if SYSTEM=="osx":
class Lightningbeam(GUI.Application):
def __init__(self):
GUI.Application.__init__(self)
self.file_type = FileType(name = "Untitled Document", suffix = "beam",
mac_creator = "LNBM", mac_type = "BEAM"), # These are optional)
def setup_menus(self, m):
m.about_cmd.enabled = 1
m.quit_cmd.enabled = 1
m.save_cmd.enabled = 1
m.save_as_cmd.enabled = 1
m.open_cmd.enabled = 1
m.new_cmd.enabled = 1
m.undo_cmd.enabled = 1
m.redo_cmd.enabled = 1
m.run_file.enabled = 1
m.run_html.enabled = 1
m.create_sc.enabled = 1
m.add_keyframe.enabled = 1
m.add_layer.enabled = 1
m.delete_layer.enabled = 1
m.bring_forward.enabled = 1
m.bring_to_front.enabled = 1
m.send_backward.enabled = 1
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
#def create_sc(self):
# pass
#def run_file(self):
# pass
class LightningbeamWindow(OSXWindow):
def __init__(self,*args,**kwargs):
OSXWindow.__init__(self,*args,**kwargs)
#def save_cmd(widget=None):
# print "to save"
#def key_down(self, event):
# if FOCUS:
# FOCUS.key_down(event)
#def key_up(self, event):
# if FOCUS:
# FOCUS.key_up(event)
app = Lightningbeam()
elif SYSTEM=="html":
app = ""
class ObjectDeletedError:
def __str__(self):
return "Object deleted!"
class htmlobj:
"""
HTML Object class. Only should be used when SYSTEM is "html".
Constructor: htmlobj (tag, [data])
tag is the name of the element in question. For example, to
create a <div> element, tag would be "div".
data is a dictionary containing attributes of the tag. For
example: htmlobj("div", {"width":120, "id":"div10}) creates:
<div id=div10 width=120>
style is a dictionary of css style attributes to be applied. For
example: htmlobj("div", {}, {"float":"left","width":"200"})
creates: <div style='float:left; width:200;'>
To access the HTML representation of an instance, call str() or the
built-in html() method.
"""
def __init__(self,tag,data={},style={}):
self.tag = tag
self.data = data
self.style = style
self.contents = []
def __str__(self):
retval = "<"+self.tag
for i in self.data:
retval+=" "+i+"="+str(self.data[i])
if self.style:
retval+=" style='"
for i in self.style:
retval+=i+":"+str(self.style[i])+";"
retval+="'"
retval+=">"+"".join((str(i) for i in self.contents))+"</"+self.tag+">\n"
return retval
def add(self, item):
self.contents.append(item)
def html(self):
return str(self)
class Window:
def __init__(self, title="", closable=True):
__windowlist__.append(self)
if SYSTEM=="gtk":
self.window = gtk.Window()
self.vbox = gtk.VBox()
self.window.add(self.vbox)
self.window.show_all()
self.window.connect("destroy",self.destroy)
elif SYSTEM=="osx":
self.window = LightningbeamWindow(width=1024,height=500, closable=closable)
if not title=="":
self.window.title = title
#components = [i._int() for i in args]
#self.vbox = GUI.Column(components, equalize="w", expand=0)
#self.window.place(self.vbox, left = 0, top = 0, right = 0, bottom = 0, sticky = 'nsew')
self.window.show()
elif SYSTEM=="html":
self.window = htmlobj("div")
elif SYSTEM=="pyglet":
self.window = pyglet.window.Window(resizable=True)
def add(self, obj,expand=False):
objint = obj._int() #Internal representation
if SYSTEM=="gtk":
self.vbox.pack_start(objint, expand, True, 0)
self.window.show_all()
elif SYSTEM=="osx":
self.window.place(objint, left=0, top=0, right=0, bottom=0, sticky="nsew")
elif SYSTEM=="html":
objint.data["width"] = "100%"
objint.data["height"] = "100%"
self.window.add(objint)
elif SYSTEM=="pyglet":
pass # how to do?
def destroy(self,data=None):
__windowlist__.remove(self)
if __windowlist__==[]:
if SYSTEM=="gtk":
gtk.main_quit()
elif SYSTEM=="osx":
pass
def maximize(self):
if SYSTEM=="gtk":
self.window.maximize()
elif SYSTEM=="pyglet":
self.window.maximize()
def set_title(self, title):
if SYSTEM=="gtk":
self.window.set_title(title)
elif SYSTEM=="osx":
self.window.title = title
elif SYSTEM=="html":
jscommunicate("document.title = "+title)
elif SYSTEM=="pyglet":
self.window.set_caption(title)
def resize(self,x,y):
if SYSTEM=="osx":
self.window.resize(width=x,height=y)
elif SYSTEM=="pyglet":
self.window.set_size(width=x, height=y)
# Widget meta-class - to prevent code duplication
# I don't seem to have any code in here. :(
# Now used as generic wrapper class
class Widget(object):
def __init__(self,obj):
self.obj = obj
def _int(self):
return self.obj
class Menu(Widget):
def __init__(self, top, menuitems):
if SYSTEM=="gtk":
if top:
self.mb = gtk.MenuBar()
else:
self.mb = gtk.Menu()
def build_menu(j, parent):
for i in j:
if type(i)==type(""):
#lambda is an anonymous function name, I'll use 'kappa' for an anonymous variable
kappa = gtk.MenuItem(i)
elif type(i)==type([]):
kappa = gtk.MenuItem(i[0])
kappabeta = gtk.Menu() #Same idea. Kappa is the menu item, kappabeta is the menu.
build_menu(i[1:],kappabeta)
kappa.set_submenu(kappabeta)
parent.append(kappa)
build_menu(menuitems,self.mb)
elif SYSTEM=="android":
for i in menuitems:
if i[0]=="File":
droid.addOptionsMenuItem(i[0], "javaevent", "pass")
elif i[0]=="Edit":
droid.addOptionsMenuItem(i[0], "javaevent", "quit()")
elif i[0]=="Help":
droid.addOptionsMenuItem(i[0], "pythonevent", "pass")
else:
droid.addOptionsMenuItem(i[0], "pythonevent", "quit()")
elif SYSTEM=="osx":
if top:
global menus
self.mb = GUI.MenuList()
# tool_menu = GUI.Menu("Tools", [("Execute", "test_cmd")])
menus = basic_menus(exclude = print_cmds)
# menus.append(tool_menu)
elif SYSTEM=="html":
pass
# I need to figure out how the menus work here.
elif SYSTEM=="pyglet":
pass
#Ditto.
def _int(self): # Returns internal GUI-specific item
return self.mb
#def menufuncs(menu,j):
def menufuncs(j):
if SYSTEM=="gtk":
def connect_menu(j,parent):
def dummifunc():
pass
agr = gtk.AccelGroup()
menu._int().get_toplevel().add_accel_group(agr)
for i in xrange(len(j)):
if type(j[i])==type(dummifunc):
parent.get_children()[i].connect("activate",j[i])
elif type(j[i])==type(()):
parent.get_children()[i].connect("activate",j[i][0])
key, mod = gtk.accelerator_parse(j[i][1])
parent.get_children()[i].add_accelerator("activate", agr, key, mod, gtk.ACCEL_VISIBLE)
elif type(j[i])==type([]):
connect_menu(j[i],parent.get_children()[i].get_submenu())
connect_menu(j,menu._int())
elif SYSTEM=="osx":
global menus
global app
def test():
print 95
for i in j:
if not i[0] in ["File", "Edit", "Help"]:
'''for n in i:
if type(n) == type(()):
print n[1].__name__
if n[1].__name__=="run_file":
app.run_file = test'''
[setattr(app,k[1].__name__, k[1]) for k in i if type(k)==type(())]
menu = GUI.Menu(i[0],[((k[0]+k[2],k[1].__name__) if (len(k)==3 and "/" in k[2]) else (k[0],k[1].__name__)) for k in i if type(k)==type(())])
#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"}
[setattr(app,cmds[k[0]],k[1]) for k in i if (k[0] in cmds)]
class VBox(Widget):
def __init__(self,width=False,height=False,*args):
if SYSTEM=="gtk":
self.vbox=gtk.VBox()
if width and height:
self.vbox.set_size_request(width,height)
[self.add(*i) for i in args]
elif SYSTEM=="osx":
seq = [i[0] for i in args] # TODO: load elements on load please
self.vbox=GUI.Column(seq)
elif SYSTEM=="html":
self.vbox = htmlobj("table")
elif SYSTEM=="pyglet":
self.vbox=None #TODO
def _int(self): # Returns internal GUI-specific item
return self.vbox
def add(self,obj,expand=False,fill=True):
objint = obj._int()
if SYSTEM=="gtk":
self.vbox.pack_start(objint,expand,fill,0)
self.vbox.show_all()
elif SYSTEM=="osx":
self.vbox.add(objint)
elif SYSTEM=="html":
if expand:
objint.data["height"]="100%"
tr = htmlobj("tr")
td = htmlobj("td")
td.add(objint)
tr.add(td)
self.vbox.add(tr)
class HBox(Widget):
def __init__(self,width=False,height=False,*args):
if SYSTEM=="gtk":
self.hbox=gtk.HBox()
if width and height:
self.hbox.set_size_request(width,height)
[self.add(*i) for i in args]
elif SYSTEM=="osx":
seq = [i[0] for i in args] # TODO: load elements on load please
self.hbox=GUI.Row(seq)
elif SYSTEM=="html":
self.hbox = htmlobj("table")
self.tr = htmlobj("tr")
self.hbox.add(self.tr)
elif SYSTEM=="pyglet":
self.hbox=None #TODO
def _int(self): # Returns internal GUI-specific item
return self.hbox
def add(self,obj,expand=False,fill=False):
objint = obj._int()
if SYSTEM=="gtk":
self.hbox.pack_start(objint,expand,fill,0)
self.hbox.show_all()
elif SYSTEM=="html":
if expand:
objint.data["width"]="100%"
td = htmlobj("td")
td.add(objint)
self.tr.add(td)
class Label(Widget):
def _gettext(self):
if SYSTEM=="osx":
return self.label.text
elif SYSTEM=="pyglet":
return self.label.text
def _settext(self,text):
if SYSTEM=="osx":
self.label.text=text
elif SYSTEM=="pyglet":
self.label.text=text
text = property(_gettext,_settext)
def __init__(self, text=""):
if SYSTEM=="osx":
self.label = OSXLabel()
self.label.text = text
elif SYSTEM=="pyglet":
self.label = pyglet.text.Label(text)
def _int(self):
if SYSTEM=="osx":
return self.label
def disable(self):
if SYSTEM=="osx":
self.label.enabled = False
elif SYSTEM=="pyglet":
self.label.color = (0, 0, 0, 100)
def enable(self):
if SYSTEM=="osx":
self.label.enabled = True
elif SYSTEM=="pyglet":
self.label.color = (0, 0, 0, 255)
class RadioGroup(Widget):
def __getitem__(self,num):
return self.buttons[num]
def __init__(self,*args):
self.buttons = []
for i in args:
self.buttons.append(RadioButton(i))
self.group = OSXRadioGroup([j._int() for j in self.buttons])
self.group.value = args[0]
self.group.action = self._action
def _int(self):
return self.group
def _getvalue(self):
return self.group.value
def _setvalue(self,value):
self.group.value = value
value = property(_getvalue, _setvalue)
def _action(self):
self.action(self)
def action(self,self1=None):
pass
class RadioButton(Widget):
def __init__(self,title):
if SYSTEM=="osx":
self.button = OSXRadioButton(title=title,value=title)
def _int(self):
return self.button
class Grid(Widget):
def __init__(self,*args):
if SYSTEM=="osx":
self.buttons = args
self.grid = GUI.Grid([[j._int() for j in i] for i in args],row_spacing=2,column_spacing=2,
align="c",equalize="wh")
elif SYSTEM=="html":
self.buttons = args
self.grid = htmlobj("table")
for i in args:
tr = htmlobj("tr")
self.grid.add(tr)
for j in i:
td = htmlobj("td")
td.add(j._int())
tr.add(td)
def _int(self):
return self.grid
class Button(Widget):
def __init__(self,text=""):
if SYSTEM=="gtk":
self.button=gtk.Button()
self.button.connect("clicked", self._onPress)
elif SYSTEM=="osx":
self.button = GUI.Button(title=text)
self.button.action = (self._onPress, self.button)
elif SYSTEM=="html":
global ids
while True:
tid = id(self)
if not tid in ids:
ids[tid]=self
self.tid = tid
break
#self.button = htmlobj("button",{"onmousedown":"pythoncommu\
#nicate('ids["+self.tid+"]._onPress('+event.pageX+','+event.pageY+')')"})
self.button = htmlobj("button",{"onmousedown":"pythoncommun\
icate('ids["+str(self.tid)+"]._onPress(ids["+str(self.tid)+"])')"})
elif SYSTEM=="pyglet":
self.button = None #TODO
def _int(self):
return self.button
def set_text(self, text):
if SYSTEM=="osx":
self.button.title = text
def set_image(self, img):
if SYSTEM=="gtk":
image=gtk.Image()
image.set_from_file(img)
self.button.add(image)
elif SYSTEM=="osx":
self.button.title = img.split("/")[-1].split(".")[0]
def set_content(self, content):
if SYSTEM=="gtk":
self.button.add(content._int())
elif SYSTEM=="html":
self.button.add(content._int())
def _onPress(self, widget):
self.onPress(self)
def onPress(self, self1):
pass
class ButtonBox(Widget):
# This class appears to be platform-independent. Nice!
def __init__(self,rows,columns):
self.buttons=[]
self.hboxes=[]
self.vbox=VBox()
for i in range(rows):
self.hboxes.append(HBox())
self.vbox.add(self.hboxes[-1])
self.buttons.append([])
for j in range(columns):
self.buttons[-1].append(Button())
self.hboxes[-1].add(self.buttons[-1][-1])
def _int(self):
return self.vbox._int()
def add(self, obj):
self.vbox.add(obj)
class ScrolledWindow(Widget):
if SYSTEM=="pyglet":
scroll_imgs = [pyglet.image.load("Themes/Default/gtk-2.0/Scrollbar/horizontal_trough.png"),
pyglet.image.load("Themes/Default/gtk-2.0/Scrollbar/scrollbar_horizontal.png"),
pyglet.image.load("Themes/Default/gtk-2.0/Scrollbar/scrollbar_horizontal_prelight.png"),
pyglet.image.load("Themes/Default/gtk-2.0/Scrollbar/vertical_trough.png"),
pyglet.image.load("Themes/Default/gtk-2.0/Scrollbar/scrollbar_vertical.png"),
pyglet.image.load("Themes/Default/gtk-2.0/Scrollbar/scrollbar_vertical_prelight.png")]
#sch controls the horizontal scrollbar, scv controls the vertical one
def __init__(self,sch=True,scv=True):
if SYSTEM=="gtk":
self.sw = gtk.ScrolledWindow()
self.sw.set_policy(gtk.POLICY_ALWAYS if sch else gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS if scv else gtk.POLICY_AUTOMATIC)
elif SYSTEM=="pyglet":
self.x = 0
self.y = 0
self.clickedhoriz = False
self.clickedvert = False
self.xoffset = 0 # Offset from mouse click point
self.yoffset = 0 #
self.hx = 0 # Scroll distance
self.vy = 0
self.horiztrough = pyglet.sprite.Sprite(self.scroll_imgs[0])
self.vertrough = pyglet.sprite.Sprite(self.scroll_imgs[3])
self.horizbar = pyglet.sprite.Sprite(self.scroll_imgs[1])
self.vertbar = pyglet.sprite.Sprite(self.scroll_imgs[4])
pass # TODO: Content.
def _int(self):
return self.sw
def add(self,obj):
objint = obj._int()
self.sw.add_with_viewport(objint)
def draw(self):
#Pyglet-specific.
if not SYSTEM=="pyglet":
print "Called from wrong GUI!"
return
self.horiztrough.set_position(self.x, self.y)
self.horiztrough.draw()
if self.clickedhoriz:
self.clickedvert = False # we should never be dragging two scrollbars at the same time!
self.horizbar.image = self.scroll_imgs[2]
self.horizbar.set_postion(self.x+self.hx, self.y)
class Frame(Widget):
# PyGUI, HTML only right now
def __init__(self):
if SYSTEM=="osx":
self.frame = GUI.Frame()
elif SYSTEM=="html":
self.frame = htmlobj("div")
def _int(self):
return self.frame
def layout_self(self, *args):
if SYSTEM=="osx":
for i in args:
self.frame.place(i[0]._int(),left=i[1],right=i[2],top=i[3],bottom=i[4],sticky=i[5], scrolling=i[6])
self.width = self.frame.width
self.height = self.frame.height
elif SYSTEM=="html":
for i in args:
i[0]._int().style["position"]="absolute"
if i[1]:
i[0]._int().style["left"]=i[1]
if i[2]:
i[0]._int().style["right"]=i[2]
if i[3]:
i[0]._int().style["top"]=i[3]
if i[4]:
i[0]._int().style["bottom"]=i[4]
if "h" in i[6]:
i[0]._int().style["overflow-x"]="scroll"
else:
i[0]._int().style["overflow-x"]="hidden"
if "v" in i[6]:
i[0]._int().style["overflow-y"]="scroll"
else:
i[0]._int().style["overflow-y"]="hidden"
self.frame.add(i[0]._int())
def setvisible(self,visible):
if SYSTEM=="osx":
if visible:
self.frame.height = self.height
# Setting the height to 0 doesn't work on Linux, so we hack around it
if PLATFORM.startswith("linux"):
self.frame._gtk_inner_widget.set_property('visible', True)
else:
self.frame.height = 0
if PLATFORM.startswith("linux"):
self.frame._gtk_inner_widget.set_property('visible', False)
print "visible:",visible
class Scale(Widget):
def __init__(self,min,val,max):
if SYSTEM=="osx":
self.scale = Slider('h')
self.scale.min_value = min
self.scale.max_value = max
self.scale.value = val
def _int(self):
return self.scale
def set_action(self,action):
if SYSTEM=="osx":
self.scale.action = action
def getval(self):
return self.scale.value
def setval(self, val):
self.scale.value = val
value = property(getval, setval)
class CheckBox(Widget):
def __init__(self,text):
if SYSTEM=="osx":
self.box = OSXCheckBox(text)
self.box.action = self._action
elif SYSTEM=="pyglet":
self.checked = False
def _int(self):
return self.box
def _action(self):
self.action()
def action(self):
pass
def get_value(self):
return self.box.value
def set_value(self, value):
self.box.value = value
value = property(get_value, set_value)
class _CR(object):
"""Internal use only. This is a class that only exists for GLViews
to pass window dimensions on to their children."""
def __init__(self):
self.x = 0
self.y = 0
self.stack = []
def save(self):
glPushAttrib(GL_ALL_ATTRIB_BITS);
glPushMatrix()
self.stack.append((self.x, self.y))
def restore(self):
self.x, self.y = self.stack.pop()
glPopMatrix()
glPopAttrib()
def translate(self, x, y):
glTranslatef(x, y, 0);
def rotate(self, r):
pass
def scale(self, sx, sy):
pass
def drawCurve(self, points, precision=20):
npoints = []
ave = misc_funcs.ave
s = range(0, len(points)-2, 2)
for i in s:
for j in range(precision):
k=1.0*(precision-j)
x=ave( ave(ave(self.x,
points[i][0],
k/precision),
ave(points[i][0],
points[i+1][0],
k/precision),
k/precision),
ave(ave(points[i][0],
points[i+1][0],
k/precision),
ave(points[i+1][0],
points[i+2][0],
k/precision),
k/precision),
k/precision)
y=ave( ave(ave(self.y,
points[i][1],
k/precision),
ave(points[i][1],
points[i+1][1],
k/precision),
k/precision),
ave(ave(points[i][1],
points[i+1][1],
k/precision),
ave(points[i+1][1],
points[i+2][1],
k/precision),
k/precision),
k/precision)
npoints.append((x, y))
glVertex2f(self.x, self.y)
glVertex2f(npoints[0][0], npoints[0][1])
for i in range(len(npoints)-1):
#drawLine(gc, drawable, npoints[i][0], npoints[i][1], npoints[i+1][0], npoints[i+1][1])
# print npoints[i][0],npoints[i][1],npoints[i+1][0],npoints[i+1][1]
glVertex2f(npoints[i][0], npoints[i][1])
glVertex2f(npoints[i+1][0], npoints[i+1][1])
glVertex2f(npoints[-1][0],npoints[-1][1])
glVertex2f(*points[2])
class Canvas(Widget):
def __init__(self,width=False,height=False):
self.objs=[]
if SYSTEM=="gtk":
self.canvas = gtk.DrawingArea()
self.canvas.add_events(gtk.gdk.EXPOSURE_MASK
| gtk.gdk.LEAVE_NOTIFY_MASK
| gtk.gdk.BUTTON_PRESS_MASK
| gtk.gdk.BUTTON_RELEASE_MASK
| gtk.gdk.KEY_PRESS_MASK
| gtk.gdk.POINTER_MOTION_MASK
| gtk.gdk.POINTER_MOTION_HINT_MASK)
if width and height:
self.canvas.set_size_request(width,height)
def onMouseDown(canvas, event):
for i in self.objs:
i._onMouseDown(event.x, event.y)
self.expose_event(self.canvas, "expose-event", self.objs)
def onMouseUp(canvas, event):
for i in self.objs:
i._onMouseUp(event.x, event.y)
self.expose_event(self.canvas, "expose-event", self.objs)
def onMouseMove(canvas, event):
for i in self.objs:
i._onMouseMove(event.x, event.y)
self.expose_event(self.canvas, "expose-event", self.objs)
self.canvas.connect("expose-event", self.expose_event, self.objs)
self.canvas.connect("button-press-event", onMouseDown)
self.canvas.connect("button-release-event", onMouseUp)
self.canvas.connect("motion_notify_event", onMouseMove)
elif SYSTEM=="osx":
if USING_GL:
class OSXCanvas(GL.GLView):
def init_context(self):
glClearColor(0.75,0.75,0.75,0.0)
def init_projection(self):
glViewport(0, 0, width, height);
glEnable( GL_TEXTURE_2D );
glEnable (GL_BLEND);
#glDisable( GL_LIGHTING)
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
def render(self):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluOrtho2D(0, width, 0, height); #TODO: width, height
glMatrixMode(GL_MODELVIEW);
cr = _CR()
cr.width = self.width
cr.height = self.height
for i in self.objs:
i.draw(cr)
def mouse_down(self, event):
self.become_target()
x, y = event.position
try:
for i in self.objs:
i._onMouseDown(x, y, button={"left":1,"right":2,"middle":3}[event.button], clicks=event.num_clicks)
except ObjectDeletedError:
return
self.update()
def mouse_drag(self, event):
x, y = event.position
for i in self.objs:
i._onMouseDrag(x, y, button={"left":1,"right":2,"middle":3}[event.button])
self.update()
def mouse_move(self, event):
global MOUSE_X, MOUSE_Y
MOUSE_X, MOUSE_Y = event.position
x, y = event.position
for i in self.objs:
i._onMouseMove(x, y, button={"left":1,"right":2,"middle":3}[event.button])
self.update()
def mouse_up(self, event):
x, y = event.position
for i in self.objs:
i._onMouseUp(x, y, button={"left":1,"right":2,"middle":3}[event.button])
self.update()
def key_down(self, event):
keydict = {127:"backspace",63272:"delete",63232:"up_arrow",63233:"down_arrow",
63235:"right_arrow",63234:"left_arrow",13:"enter",9:"tab",
63236:"F1",63237:"F2",63238:"F3",63239:"F4",63240:"F5",
63241:"F6",63242:"F7",63243:"F8",27:"escape"}
if not event.unichars=='':
if ord(event.unichars) in keydict:
key = keydict[ord(event.unichars)]
else:
key = event.unichars
else:
key = event.key.upper()
for i in self.objs:
i._onKeyDown(key)
self.update()
def key_up(self, event):
pass
self.canvas = OSXCanvas()
self.canvas.update()
else:
class OSXCanvas (ScrollableView):
def draw(self, canvas, update_rect):
canvas.backcolor = Color("#888888").pygui
canvas.erase_rect(update_rect)
canvas.fillcolor = Color("#ffffff").pygui
canvas.fill_rect((0,0,WIDTH,HEIGHT))
for i in self.objs:
try:
i.draw(canvas)
except:
traceback.print_exc()
def mouse_down(self, event):
self.become_target()
x, y = event.position
try:
try:
for i in self.objs:
i._onMouseDown(x, y, button={"left":1,"right":2,"middle":3}[event.button], clicks=event.num_clicks)
except ObjectDeletedError:
return
except:
traceback.print_exc()
self.invalidate_rect([0,0,self.extent[0],self.extent[1]])
def mouse_drag(self, event):
x, y = event.position
for i in self.objs:
try:
if event.button:
i._onMouseDrag(x, y, button={"left":1,"right":2,"middle":3}[event.button])
else:
i._onMouseDrag(x, y, button=None)
except:
traceback.print_exc()
self.invalidate_rect([0,0,self.extent[0],self.extent[1]])
def mouse_move(self, event):
x, y = event.position
for i in self.objs:
i._onMouseMove(x, y)
self.invalidate_rect([0,0,self.extent[0],self.extent[1]])
def mouse_up(self, event):
x, y = event.position
for i in self.objs:
i._onMouseUp(x, y, button={"left":1,"right":2,"middle":3}[event.button], clicks=event.num_clicks)
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",
63235:"right_arrow",63234:"left_arrow",13:"enter",9:"tab",
63236:"F1",63237:"F2",63238:"F3",63239:"F4",63240:"F5",
63241:"F6",63242:"F7",63243:"F8",27:"escape"}
if not event.unichars=='':
if ord(event.unichars) in keydict:
key = keydict[ord(event.unichars)]
else:
key = event.unichars
else:
key = event.key.upper()
for i in self.objs:
i._onKeyDown(key)
self.invalidate_rect([0,0,self.extent[0],self.extent[1]])
def key_up(self, event):
pass
self.canvas = OSXCanvas(extent = (width, height), scrolling = 'hv')
self.canvas.objs = self.objs
elif SYSTEM=="html":
global ids
while True:
tid = id(self)
ids[tid]=self
self.tid = tid
break
self.canvas = htmlobj("canvas",{"id":"canvas"+str(self.tid)})
jsdefine("drawcanvas","(tid)",'''
var canvas = document.getElementById("canvas"+tid.toString());
var ctx = canvas.getContext("2d")
ctx.clearRect(0, 0, canvas.width, canvas.height)
for (i in cchildren[tid]) {
i.draw(ctx);
}''')
jscommunicate("cchildren["+str(self.tid)+"]="+str(self.objs))
def _int(self):
return self.canvas
def expose_event(self, canvas, event, objs):
x,y,w,h = canvas.allocation
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, w,h)
cr = cairo.Context(surface)
cra = canvas.window.cairo_create()
cr.set_source_rgb(0.5, 0.5, 0.5)
cr.paint()
for i in objs:
i.draw(cr)
cra.set_source_surface(surface)
cra.paint()
def draw(self):
if SYSTEM=="gtk":
self.expose_event(self.canvas, "draw_event", self.objs)
elif SYSTEM in ["osx", "android"]:
self.canvas.invalidate_rect((0,0,self.canvas.extent[0],self.canvas.extent[1]))
elif SYSTEM=="html":
jscommunicate("drawcanvas("+self.tid+")")
def add(self, obj, x, y):
obj.x = x
obj.y = y
self.objs.append(obj)
if SYSTEM=="html":
jscommunicate("cchildren["+str(self.tid)+"]="+str(self.objs))
def delete(self, obj):
self.objs.remove(obj)
del obj
self.draw()
if SYSTEM=="html":
jscommunicate("cchildren["+str(self.tid)+"]="+str(self.objs))
def key_down(self, event):
if SYSTEM=="osx":
self.canvas.key_down(event)
def key_up(self, event):
if SYSTEM=="osx":
self.canvas.key_up(event)
class TextView(Widget):
def _gettext(self):
if SYSTEM=="osx":
return self.box.text
def _settext(self, text):
if SYSTEM=="osx":
self.box.text = text
text = property(_gettext, _settext)
def __init__(self,editable=True,width=False,height=False,code=False):
if SYSTEM=="gtk":
self.sw=ScrolledWindow()
self.box=gtk.TextView()
if width and height:
self.sw._int().set_size_request(width,height)
self.box.set_cursor_visible(editable)
self.sw._int().add_with_viewport(self.box)
#self.sw._int().set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
def scroll(self,widget):
self.scroll_to_mark(self.get_buffer().get_insert(), 0)
self.box.connect("key-press-event",scroll)
elif SYSTEM=="osx":
class OSXTextEditor(GUI.TextEditor):
def mouse_down(self, event):
self.become_target()
GUI.TextEditor.mouse_down(self, event)
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)
elif SYSTEM=="html":
self.box = htmlobj("textarea")
def _int(self):
if SYSTEM=="gtk":
return self.sw._int()
elif SYSTEM=="osx":
return self.box
elif SYSTEM=="html":
return self.box
def scroll_bottom(self):
if SYSTEM=="osx":
self.scroll_page_down();
self.box.invalidate()
class TextEntry(Widget):
def __init__(self,text="",password=False):
if SYSTEM=="osx":
self.entry = TextField(text=text,multiline=False,password=password)
def _int(self):
if SYSTEM=="osx":
return self.entry
def disable(self):
self.entry.enabled = False
def enable(self):
self.entry.enabled = True
def set_action(self,action):
if SYSTEM=="osx":
self.entry.enter_action = action
def get_text(self):
return self.entry.text
def set_text(self, text):
self.entry.text = text
text = property(get_text, set_text)
class Image(object):
def __getstate__(self):
dict = self.__dict__.copy()
print dict
dict['image'] = None
dict['pilimage'] = None
return dict
def __init__(self,image,x=0,y=0,animated=False,canvas=None,htiles=1,vtiles=1,skipl=False):
if not skipl:
global Library
Library.append(self)
self.x = x
self.y = y
self.minx = x
self.miny = y
self.rotation = 0
self.xscale = 1
self.yscale = 1
self.filled = True
self.linecolor = None
self.fillcolor = None
self.name = image.split(sep)[-1]
self.iname = None
self.path = image
self.type="Image"
if USING_GL:
self.pilimage = PILimage.open(image)
# This is an OpenGL texture ID.
self.gltexture = self.loadGLImage(file = image)
if animated:
self.animated = True
self.htiles = htiles
self.vtiles = vtiles
self.pointer = 0
self.canvas = canvas
def animate(self):
self.pointer = (self.pointer+1)%(htiles*vtiles)
if SYSTEM in ["gtk", "osx"]:
self.canvas._int().invalidate_rect([self.x, self.y, self.x+self.image.bounds[2]/self.htiles, self.y+self.image.bounds[3]/self.vtiles])
else:
jscommunicate("drawcanvas("+str(self.canvas.tid)+")")
r = misc_funcs.RepeatTimer(0.1, animate, args=[self])
r.daemon = True
r.start()
else:
self.animated = False
if SYSTEM=="osx":
self.image = GUI.Image(file = image)
if self.animated:
self.maxx = self.x+self.image.bounds[2]/self.htiles
self.maxy = self.y+self.image.bounds[3]/self.vtiles
else:
self.maxx = self.x+self.image.bounds[2]
self.maxy = self.y+self.image.bounds[3]
elif SYSTEM=="html":
self.image = htmlobj("img", {"src":image})
#TODO: ##### FIGURE OUT WIDTH, HEIGHT #####
if self.animated:
self.maxx = self.x#+self.image.width[2]/self.htiles
self.maxy = self.y#+self.image.height[3]/self.vtiles
else:
self.maxx = self.x#+self.image.width[2]
self.maxy = self.y#+self.image.height[3]
self.shapedata = [['M',0,0],['L',self.maxx,0],['L',self.maxx,self.maxy],['L',0,self.maxy],['L',0,0]]
def _int(self):
return self.image
def draw(self, cr=None, parent=None, rect=None):
if SYSTEM=="android":
pass
elif SYSTEM=="osx":
if USING_GL:
pass
glEnable(GL_TEXTURE_2D);
glColor3f(0.5,0.5,0.5);
#self.gltexture.bind()
#self.gltexture.gl_tex_image_2d(self.image, with_mipmaps=True)
glBindTexture(GL_TEXTURE_2D, self.gltexture)
if self.animated:
src_rect = [(1.0/self.htiles)*(self.pointer%self.htiles),
(1.0/self.vtiles)*(self.pointer/self.htiles),
(1.0/self.htiles)*(self.pointer%self.htiles+1),
(1.0/self.vtiles)*(self.pointer/self.htiles+1)]
width = self.image.bounds[2]/self.htiles
height = self.image.bounds[3]/self.vtiles
else:
src_rect = [0.0, 0.0, 1.0, 1.0]
width, height = self.image.bounds
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0);
#glTexCoord2f(src_rect[0], src_rect[1]);
glVertex2f( self.x, cr.height-(self.y));
glTexCoord2f(1.0, 0.0);
#glTexCoord2f(src_rect[2], src_rect[1]);
glVertex2f(width+self.x, cr.height-(self.y));
glTexCoord2f(1.0, 1.0);
#glTexCoord2f(src_rect[2], src_rect[3]);
glVertex2f( width+self.x, cr.height-(height+self.y));
glTexCoord2f(0.0, 1.0);
#glTexCoord2f(src_rect[0], src_rect[3]);
glVertex2f( self.x, cr.height-(height+self.y));
# print src_rect
glEnd();
else:
cr.gsave()
if sep=="\\":
# Very ugly hack for Windows. :(
# Windows doesn't respect coordinate transformations
# with respect to translation, so we have to do this
# bit ourselves.
# Rotation in radians
radrot = parent.group.rotation*math.pi/180
# Coordinate transform: multiplication by a rotation matrix
cr.translate(self.x*math.cos(radrot)-self.y*math.sin(radrot), self.x*math.sin(radrot)+self.y*math.cos(radrot))
else:
cr.translate(self.x,self.y)
cr.rotate(self.rotation)
cr.scale(self.xscale*1.0, self.yscale*1.0)
if self.animated:
src_rect = self.image.bounds
# (i%4)%6, i/4
src_rect = [(src_rect[2]/self.htiles)*(self.pointer%self.htiles),
(src_rect[3]/self.vtiles)*(self.pointer/self.htiles),
(src_rect[2]/self.htiles)*(self.pointer%self.htiles+1),
(src_rect[3]/self.vtiles)*(self.pointer/self.htiles+1)]
#src_rect = [16*self.pointer,0,16+16*self.pointer,32]
#print [self.x, self.y, self.x+self.image.bounds[2]/self.htiles, self.y+self.image.bounds[3]/self.vtiles]
dst_rect = [self.x, self.y, self.image.bounds[2]/self.htiles+self.x, self.image.bounds[3]/self.vtiles+self.y]
self.image.draw(cr, src_rect, dst_rect)
else:
src_rect = self.image.bounds
dst_rect = [self.x,self.y,self.x+src_rect[2],self.y+src_rect[3]]
self.image.draw(cr, src_rect, dst_rect)
cr.grestore()
elif SYSTEM=="html":
cr.save()
pass
def set_image(self,img):
if SYSTEM=="osx":
self.image = GUI.Image(file = img)
if USING_GL:
self.gltexture = self.loadGLImage(file = img)
def loadGLImage(self, file = None ):
"""Load an image file as a 2D texture using PIL"""
if not file:
file = self.path
im = PILImage.open(file)
try:
ix, iy, image = im.size[0], im.size[1], im.tostring("raw", "RGBA", 0, -1)
except SystemError:
ix, iy, image = im.size[0], im.size[1], im.tostring("raw", "RGBX", 0, -1)
ID = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, ID)
glPixelStorei(GL_UNPACK_ALIGNMENT,1)
glTexImage2D(
GL_TEXTURE_2D, 0, 3, ix, iy, 0,
GL_RGBA, GL_UNSIGNED_BYTE, image
)
return ID
def hitTest(self,x,y):
hits = False
# points "a" and "b" forms the anchored segment.
# point "c" is the evaluated point
def IsOnLeft(a, b, c):
return Area2(a, b, c) > 0
def IsOnRight(a, b, c):
return Area2(a, b, c) < 0
def IsCollinear(a, b, c):
return Area2(a, b, c) == 0
# calculates the triangle's size (formed by the "anchor" segment and additional point)
def Area2(a, b, c):
return (b[0]-a[0])*(c[1]-a[1])-(c[0]-a[0])*(b[1]-a[1])
def intersects(a,b,c,d):
return not (IsOnLeft(a,b,c) != IsOnRight(a,b,d))
def ccw(a,b,c):
return (c[1]-a[1])*(b[0]-a[0]) > (b[1]-a[1])*(c[0]-a[0])
def intersect(a,b,c,d):
return ccw(a,c,d) != ccw(b,c,d) and ccw(a,b,c) != ccw(a,b,d)
for i in xrange(len(self.shapedata)):
hits = hits != intersect(self.shapedata[i-1][1:3],self.shapedata[i][1:3],[x,y],[x,sys.maxint])
return hits
def onMouseDown(self, self1, x, y, button=1, clicks=1):
pass
def onMouseDrag(self, self1, x, y, button=1, clicks=1):
pass
def onMouseUp(self, self1, x, y, button=1, clicks=1):
pass
def onMouseMove(self, self1, x, y, button=1, clicks=1):
pass
def onKeyDown(self, self1, key):
pass
def onKeyUp(self, self1, key):
pass
def print_sc(self):
return ".png "+self.name+" \""+self.path+"\"\n"
class Shape (object):
def __init__(self,x=0,y=0,rotation=0,fillcolor=None,linecolor=None):
global SITER
global Library
Library.append(self)
self.x=x
self.y=y
self.rotation=rotation
self.xscale = 1
self.yscale = 1
self.linecolor = linecolor if linecolor else LINECOLOR
self.fillcolor = fillcolor if fillcolor else FILLCOLOR
self.linewidth = 2
self.shapedata=[]
self.filled=False
self.type="Shape"
self.iname = None
####################-----TEMPORARY-----#########################
self.name = "s"+str(int(random.random()*10000))+str(SITER)
SITER+=1
################################################################
def draw(self,cr=None,parent=None,rect=None):
if SYSTEM=="gtk":
cr.save()
cr.translate(self.x,self.y)
cr.rotate(self.rotation*math.pi/180)
cr.scale(self.xscale*1.0, self.yscale*1.0)
cr.set_source(self.linecolor.cairo)
cr.set_line_width(max(self.linewidth,1))
for i in self.shapedata:
if i[0]=="M":
cr.move_to(i[1],i[2])
elif i[0]=="L":
cr.line_to(i[1],i[2])
elif i[0]=="C":
cr.curve_to(i[1],i[2],i[3],i[4],i[5],i[6])
if self.filled:
cr.stroke_preserve()
cr.set_source(self.fillcolor.cairo)
cr.fill()
else:
cr.stroke()
cr.restore()
elif SYSTEM=="android":
global tb
tb+="cr.save()\n"
tb+="cr.translate("+str(self.x)+","+str(self.y)+")\n"
tb+="cr.rotate("+str(self.rotation*math.pi/180)+")\n"
tb+="cr.scale("+str(self.xscale)+"*1.0, "+str(self.yscale)+"*1.0)\n"
tb+="cr.lineWidth = "+str(max(self.linewidth,1))+"\n"
if type(self.fill)==type([]):
tb+="cr.fillStyle = \""+rgb2hex(self.fill[0],self.fill[1],self.fill[2])+"\"\n"
for i in self.shapedata:
if i[0]=="M":
tb+="cr.moveTo("+str(i[1])+","+str(i[2])+")\n"
elif i[0]=="L":
tb+="cr.lineTo("+str(i[1])+","+str(i[2])+")\n"
elif i[0]=="C":
tb+="cr.bezierCurveTo("+str(i[1])+","+str(i[2])+","+str(i[3])+","+str(i[4])+","+str(i[5])+","+str(i[6])+")\n"
if self.filled:
tb+="cr.stroke()\n"
tb+="cr.fill()\n"
else:
tb+="cr.stroke()\n"
tb+="cr.restore()\n"
elif SYSTEM=="osx":
if USING_GL:
cr.save()
cr.translate(self.x, cr.height-self.y)
# cr.translate(MOUSE_X, MOUSE_Y)
cr.rotate(self.rotation)
cr.scale(self.xscale*1.0, self.yscale*1.0)
#pencolor, fillcolor, pensize
#Temporary.
glColor3f(1.0,0.0,0.0)
glBegin(GL_LINES)
for i in self.shapedata:
if i[0]=="M":
point = (i[1], i[2])
#glVertex2f(point[0], cr.height-point[1])
cr.x, cr.y = point
elif i[0]=="L":
point = (i[1], i[2])
#glVertex2f(point[0], cr.height-point[1])
glVertex2f(cr.x, -cr.y)
glVertex2f(point[0], -point[1])
cr.x, cr.y = point
elif i[0]=="C":
pointa = (i[1], -i[2])
pointb = (i[3], -i[4])
pointc = (i[5], -i[6])
#TODO: curve
#glVertex2f(pointc[0], -pointc[1])
#glVertex2f(pointc[0], -pointc[1])
cr.drawCurve([ pointa, pointb, pointc])
cr.x, cr.y = pointc
glEnd()
cr.restore()
else:
cr.gsave()
if sep=="\\":
# Very ugly hack for Windows. :(
# Windows doesn't respect coordinate transformations
# with respect to translation, so we have to do this
# bit ourselves.
# Rotation in radians
radrot = parent.group.rotation*math.pi/180
# Coordinate transform: multiplication by a rotation matrix
cr.translate(self.x*math.cos(radrot)-self.y*math.sin(radrot), self.x*math.sin(radrot)+self.y*math.cos(radrot))
else:
pass
# cr.translate(self.x,self.y)
cr.translate(self.x/(self.xscale*1.0),self.y/(self.yscale*1.0))
cr.rotate(self.rotation)
cr.scale(self.xscale*1.0, self.yscale*1.0)
cr.newpath()
cr.pencolor = self.linecolor.pygui
cr.fillcolor = self.fillcolor.pygui
cr.pensize = max(self.linewidth,1)
for i in self.shapedata:
if i[0]=="M":
point = (i[1], i[2])
cr.moveto(point[0],point[1])
elif i[0]=="L":
point = (i[1], i[2])
cr.lineto(point[0],point[1])
elif i[0]=="C":
pointa = (i[1], i[2])
pointb = (i[3], i[4])
pointc = (i[5], i[6])
### Mac OSX needs custom PyGUI for this to work ###
cr.curveto((pointa[0],pointa[1]),(pointb[0],pointb[1]),(pointc[0],pointc[1]))
if self.filled:
cr.closepath()
cr.fill_stroke()
else:
cr.stroke()
cr.grestore()
elif SYSTEM=="html":
tb = ""
tb+="cr.save()\n"
tb+="cr.translate("+str(self.x)+","+str(self.y)+")\n"
tb+="cr.rotate("+str(self.rotation*math.pi/180)+")\n"
tb+="cr.scale("+str(self.xscale)+"*1.0, "+str(self.yscale)+"*1.0)\n"
tb+="cr.lineWidth = "+str(max(self.linewidth,1))+"\n"
if type(self.fill)==type([]):
tb+="cr.fillStyle = \""+rgb2hex(self.fill[0],self.fill[1],self.fill[2])+"\"\n"
for i in self.shapedata:
if i[0]=="M":
tb+="cr.moveTo("+str(i[1])+","+str(i[2])+")\n"
elif i[0]=="L":
tb+="cr.lineTo("+str(i[1])+","+str(i[2])+")\n"
elif i[0]=="C":
tb+="cr.bezierCurveTo("+str(i[1])+","+str(i[2])+","+str(i[3])+","+str(i[4])+","+str(i[5])+","+str(i[6])+")\n"
if self.filled:
tb+="cr.stroke()\n"
tb+="cr.fill()\n"
else:
tb+="cr.stroke()\n"
tb+="cr.restore()\n"
jscommunicate(tb)
def line(self,x,y,x1=False,y1=False):
pass
def curve(self,x,y,x1,y1,x2=False,y2=False):
pass
def edit(self, arguments):
pass #no idea how this will work yet
def move(self, x, y):
pass
def scale(self, width, height):
try:
xfactor = width/self.maxx
yfactor = height/self.maxy
def scale_section(section):
try:
if section[0] in ["M", "L"]:
section[1]*=xfactor
section[2]*=yfactor
elif section[0]=="C":
section[1]*=xfactor
section[2]*=yfactor
section[3]*=xfactor
section[4]*=yfactor
section[5]*=xfactor
section[6]*=yfactor
except ZeroDivisionError:
print "Divided by zero while scaling a tiny segment. Continuing happily."
result = [scale_section(i) for i in self.shapedata]
except ZeroDivisionError:
print "Divided by zero! Universe collapsing."
def hitTest(self,x,y):
hits = False
# points "a" and "b" forms the anchored segment.
# point "c" is the evaluated point
def IsOnLeft(a, b, c):
return Area2(a, b, c) > 0
def IsOnRight(a, b, c):
return Area2(a, b, c) < 0
def IsCollinear(a, b, c):
return Area2(a, b, c) == 0
# calculates the triangle's size (formed by the "anchor" segment and additional point)
def Area2(a, b, c):
return (b[0]-a[0])*(c[1]-a[1])-(c[0]-a[0])*(b[1]-a[1])
def intersects(a,b,c,d):
return not (IsOnLeft(a,b,c) != IsOnRight(a,b,d))
def ccw(a,b,c):
return (c[1]-a[1])*(b[0]-a[0]) > (b[1]-a[1])*(c[0]-a[0])
def intersect(a,b,c,d):
return ccw(a,c,d) != ccw(b,c,d) and ccw(a,b,c) != ccw(a,b,d)
for i in xrange(len(self.shapedata)):
hits = hits != intersect(self.shapedata[i-1][1:3],self.shapedata[i][1:3],[x,y],[x,sys.maxint])
print hits, x, y
return hits
def localtransform(self, x, y, parent):
x,y = parent.localtransform(x,y)
nx = x*math.cos(-self.rotation)-y*math.sin(-self.rotation)+self.x
ny = x*math.sin(-self.rotation)+y*math.cos(-self.rotation)+self.y
return nx, ny
def revlocaltransform(self, x, y, parent):
x,y = parent.revlocaltransform(x,y)
radrot = self.rotation*math.pi/180
nx = x*math.cos(radrot)-y*math.sin(radrot)+self.x
ny = x*math.sin(radrot)+y*math.cos(radrot)+self.y
return nx, ny
def getminx(self):
return min([i[1] for i in self.shapedata])
def getminy(self):
return min([i[2] for i in self.shapedata])
def getmaxx(self):
return max([i[1] for i in self.shapedata])
def getmaxy(self):
return max([i[2] for i in self.shapedata])
def onMouseDown(self, self1, x, y, button=1, clicks=1):
pass
def onMouseDrag(self, self1, x, y, button=1, clicks=1):
pass
def onMouseUp(self, self1, x, y, button=1, clicks=1):
pass
def onMouseMove(self, self1, x, y, button=1, clicks=1):
pass
def onKeyDown(self, self1, key):
pass
def onKeyUp(self, self1, key):
pass
minx = property(getminx)
miny = property(getminy)
maxx = property(getmaxx)
maxy = property(getmaxy)
def print_sc(self):
retval = ""
retval+=".outline "+self.name+"outline:\n"
retval+=" ".join([" ".join([str(x) for x in a]) for a in self.shapedata])+"\n.end\n"
if self.filled:
if self.fillcolor.type=="Image":
retval+=".filled "+self.name+" outline="+self.name+"outline fill="+self.fillcolor.val.split('/')[-1].replace(' ','_').replace('.','_')+" color="+self.linecolor.rgb+" line="+str(self.linewidth)+"\n"
else:
retval+=".filled "+self.name+" outline="+self.name+"outline fill="+self.fillcolor.rgb+" color="+self.linecolor.rgb+" line="+str(self.linewidth)+"\n"
else:
retval+=".filled "+self.name+" outline="+self.name+"outline fill=#00000000 color="+self.linecolor.rgb+" line="+str(self.linewidth)+"\n"
return retval
def print_html(self):
retval = "var "+self.name+" = new Shape();\n"+self.name+"._shapedata = "+str(self.shapedata)+";\n"
if self.fillcolor.type=="Image":
retval += self.name+".fill = "+self.fillcolor.val.split('/')[-1].replace(' ','_').replace('.','_')+";\n"+self.name+".line = \""+self.linecolor.rgb+"\";\n"
else:
retval += self.name+".fill = \""+self.fillcolor.rgb+"\";\n"+self.name+".line = \""+self.linecolor.rgb+"\";\n"
retval += self.name+".filled = "+str(self.filled).lower()+";\n"
return retval
class Text (object):
def __init__(self,text="",x=0,y=0):
global SITER
global Library
Library.append(self)
self.text = text
self.x = x
self.y = y
self.rotation = 0
self.xscale = 1
self.yscale = 1
self.fill = TEXTCOLOR
self.font = Font(FONT,16)
self.dynamic = False
self.variable = None
self.password = False
self.wordwrap = False
self.multiline = False
self.html = False
self.editable = False
self.selectable = True
self.border = False
# self.width = self.font.width(self.text)
self.height = self.font.height
self.iname = None
self.hwaccel = False
self.type="Text"
self.name = "t"+str(int(random.random()*10000))+str(SITER)
self.editing = False
self.cursorpos = len(self.text)
SITER+=1
def draw(self,cr=None,parent=None,rect=None):
if SYSTEM=="osx":
if USING_GL:
pass
else:
cr.font = self.font
cr.textcolor = self.fill.pygui
cr.gsave()
#cr.moveto(self.x,self.y)
if sep=="\\":
# Very ugly hack for Windows. :(
# Windows doesn't respect coordinate transformations
# with respect to translation, so we have to do this
# bit ourselves.
# Rotation in radians
radrot = parent.group.rotation*math.pi/180
# Coordinate transform: multiplication by a rotation matrix
cr.translate(self.x*math.cos(radrot)-self.y*math.sin(radrot), self.x*math.sin(radrot)+self.y*math.cos(radrot))
else:
cr.translate(self.x,self.y)
if self.editing:
w = self.font.width(self.text)
d = self.font.descent
h = self.font.height
lines = self.text.count('\n')
cr.newpath()
cr.moveto(0,d+h*lines)
cr.lineto(w,d+h*lines)
cr.lineto(w,-h)
cr.lineto(0,-h)
cr.lineto(0,d+h*lines)
cr.pencolor = Color([0,0,0]).pygui
cr.fillcolor = Color([1,1,1]).pygui
cr.fill_stroke()
cr.fill()
if '\n' in self.text[:self.cursorpos]:
cw = self.font.width(self.text[self.text.rindex('\n',0,self.cursorpos):self.cursorpos])
else:
cw = self.font.width(self.text[:self.cursorpos])
cr.newpath()
elines = self.text[:self.cursorpos].count('\n')
cr.moveto(cw,d+h*elines)
cr.lineto(cw,-h+h*elines)
cr.stroke()
cr.newpath()
cr.moveto(0,0)
cr.show_text(self.text)
cr.grestore()
def hitTest(self, x, y):
self.height = self.font.height
if 0<x<self.width and -self.height<y<0:
return True
def getwidth(self):
return self.font.width(self.text)
def getminx(self):
return 0
def getminy(self):
return -self.height
def getmaxx(self):
return self.width
def getmaxy(self):
return 0
def getsize(self):
return self.font.size
def setsize(self,size):
self.font = Font(self.font.family,size,self.font.style)
self.height = self.font.height
minx = property(getminx)
miny = property(getminy)
maxx = property(getmaxx)
maxy = property(getmaxy)
size = property(getsize,setsize)
width= property(getwidth)
def onMouseDown(self, self1, x, y, button=1, clicks=1):
pass
def onMouseDrag(self, self1, x, y, button=1):
pass
def onMouseUp(self, self1, x, y, button=1, clicks=1):
pass
def onMouseMove(self, self1, x, y, button=1):
pass
def onKeyDown(self, self1, key):
if key == "\b":
self.text = self.text[:-1]
elif key == "enter":
self.text = self.text[:self.cursorpos]+"\n"+self.text[self.cursorpos:]
self.height = self.font.height*(self.text.count('\n')+1)
self.cursorpos += 1
elif key == "backspace":
if self.cursorpos>0:
self.text = self.text[:self.cursorpos-1]+self.text[self.cursorpos:]
self.cursorpos -= 1
elif key == "delete":
if self.cursorpos<len(self.text):
self.text = self.text[:self.cursorpos]+self.text[self.cursorpos+1:]
elif key == "left_arrow":
if self.cursorpos>0:
self.cursorpos -= 1
elif key == "right_arrow":
if self.cursorpos<len(self.text):
self.cursorpos += 1
elif key == "up_arrow":
if '\n' in self.text[:self.cursorpos]:
lpos = self.text[:self.cursorpos].rindex('\n', 0, self.cursorpos)
if '\n' in self.text[:lpos]:
llpos = self.text[:lpos].rindex('\n',0,lpos)
else:
llpos = -1 # to account for no \n preceding it
self.cursorpos = min(self.cursorpos-lpos+llpos,lpos)
elif key == "down_arrow":
if '\n' in self.text[self.cursorpos:]:
if '\n' in self.text[:self.cursorpos]:
lpos = self.text[:self.cursorpos].rindex('\n', 0, self.cursorpos)
else:
lpos = -1
npos = self.text[self.cursorpos:].index('\n')
if '\n' in self.text[self.cursorpos+npos+1:]:
nnpos = self.text[self.cursorpos+npos+1:].index('\n')
else:
nnpos = len(self.text[self.cursorpos:])
self.cursorpos = min(self.cursorpos+npos+self.cursorpos-lpos,self.cursorpos+npos+nnpos+1)
else:
self.text=self.text[:self.cursorpos]+str(key)+self.text[self.cursorpos:]
self.cursorpos += 1
if not key=="enter":
if len(undo_stack)>0:
if isinstance(undo_stack[-1], maybe):
if undo_stack[-1].edit.obj==self:
undo_stack[-1].edit.to_attrs={"text":self.text, "cursorpos":self.cursorpos}
else:
undo_stack.append(maybe("text", self, {"text":self.text, "cursorpos":self.cursorpos}))
else:
undo_stack.append(maybe("text", self, {"text":self.text, "cursorpos":self.cursorpos}))
else:
undo_stack.append(maybe("text", self, {"text":self.text, "cursorpos":self.cursorpos}))
else:
undo_stack[-1] = undo_stack[-1].complete({"text":self.text, "cursorpos":self.cursorpos})
clear(redo_stack)
pass
def onKeyUp(self, self1, key):
pass
def print_sc(self):
retval = ".font "+''.join(self.font.family.split(' '))+self.name+" filename=\""\
+FONT_PATH+self.font.family+".ttf\"\n"
if self.dynamic:
retval+=".edittext "+self.name+" width="+str(self.width)+" height="+str(self.height)\
+" font="+''.join(self.font.family.split(' '))+self.name+" text=\""+self.text\
+"\" color="+self.fill.rgb+" size="+str(self.font.size)+"pt"
if self.variable:
retval+=" variable="+self.variable
if self.password:
retval+=" password"
if self.wordwrap:
retval+=" wordwrap"
if self.multiline:
retval+=" multiline"
if self.html:
retval+=" html"
if self.border:
retval+=" border"
if self.editable:
retval+="\n"
if not self.selectable:
retval+=" noselect"
else:
retval+=" readonly\n"
else:
retval+=".text "+self.name+" font="+''.join(self.font.family.split(' '))+self.name\
+" text=\""+self.text+"\" color="+self.fill.rgb+" size="+str(self.font.size)\
+"pt\n"
return retval
def print_html(self):
retval = "var "+self.name+" = new TextField();\n"+self.name+".text = \""+self.text\
+"\";\n"+self.name+".hwaccel = "+str(self.hwaccel).lower()+"\n"
return retval
class Sound:
"""Class for storing sounds in."""
def __init__(self, data, name, path, info):
global Library
Library.append(self)
self.data = data
self.name = name.replace(" ", "_")
self.x = 0
self.y = 0
self.rotation = 0
self.xscale = 0
self.yscale = 0
self.path = path
self.iname = None
reading_comments_flag = False
other = ''
for l in info.splitlines():
if( not l.strip() ):
continue
if( reading_comments_flag and l.strip() ):
if( comments ):
comments += '\n'
comments += l
else:
if( l.startswith('Input File') ):
input_file = l.split(':',1)[1].strip()[1:-1]
elif( l.startswith('Channels') ):
num_channels = int(l.split(':',1)[1].strip())
elif( l.startswith('Sample Rate') ):
sample_rate = int(l.split(':',1)[1].strip())
elif( l.startswith('Precision') ):
bits_per_sample = int(l.split(':',1)[1].strip()[0:-4])
elif( l.startswith('Duration') ):
tmp = l.split(':',1)[1].strip()
tmp = tmp.split('=',1)
duration_time = tmp[0]
duration_samples = int(tmp[1].split(None,1)[0])
elif( l.startswith('Sample Encoding') ):
encoding = l.split(':',1)[1].strip()
elif( l.startswith('Comments') ):
comments = ''
reading_comments_flag = True
else:
if( other ):
other += '\n'+l
else:
other = l
print >>sys.stderr, "Unhandled:",l
self.sample_rate = int(sample_rate)
self.duration_samples = int(duration_samples)
self.duration_time = int(duration_time.split(':')[0])*3600+int(duration_time.split(':')[1])*60+float(duration_time.split(':')[2])
def draw(self, cr, transform):
pass
def draw_frame(self, cr, transform):
if SYSTEM=="osx":
cr.newpath()
# cr.moveto(0,16)
chunk_size = int(self.duration_samples/(self.duration_time*FRAMERATE*16))
print chunk_size
print self.duration_samples/chunk_size
for i in xrange(self.duration_samples/chunk_size):
j = abs(NP.amax(self.data[i*chunk_size:(i+1)*chunk_size])/65536.0)
cr.moveto(i,16-j*16)
cr.lineto(i,16+j*16)
# cr.lineto(self.duration_time*16*FRAMERATE,16)
cr.stroke()
def hitTest(self, x, y):
return False
def print_sc(self):
retval = ".sound "+self.name+" \""+self.path+"\"\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"
retval = retval + self.name.replace(".","_")+"._sound.load();\n"+self.name.replace(".","_")+".duration = "+self.name.replace(".","_")+"._sound.duration\n"
return retval
class framewrapper (object):
#def __getstate__(self):
# dict = self.__dict__.copy()
# dict['parent'] = None
# return dict
#Wraps object per-frame. Allows for changes in position, rotation, scale.
def __init__(self, obj, x, y, rot, scalex, scaley, parent=None):
self.obj = obj
self.x = obj.x = x
self.y = obj.y = y
self.rot = obj.rot = rot
self.scalex = self.xscale = obj.scalex = scalex
self.scaley = self.yscale = obj.scaley = scaley
self.level = False # don't try to descend into a framewrapper
self.type = obj.__class__.__name__
if obj.__class__.__name__=="Shape":
self.filled = obj.filled
self.linecolor = obj.linecolor
self.fillcolor = obj.fillcolor
self.name = obj.name
self.parent = parent
def draw(self,cr,transform):
pass
self.update()
self.obj.draw(cr,transform)
def update(self):
self.obj.x = self.x
self.obj.y = self.y
self.obj.rot = self.rot
self.obj.scalex = self.scalex
self.obj.scaley = self.scaley
self.obj.xscale = self.xscale
self.obj.yscale = self.yscale
if self.type=="Shape":
self.obj.filled = self.filled
self.obj.linecolor = self.linecolor
self.obj.fillcolor = self.fillcolor
def _onMouseDown(self, x, y, button=1, clicks=1):
self.obj.onMouseDown(self,x, y, button, clicks)
def _onMouseUp(self, x, y, button=1, clicks=1):
self.obj.onMouseUp(self,x, y, button)
def _onMouseMove(self, x, y, button=1):
self.obj.onMouseMove(self, x, y, button)
def _onMouseDrag(self, x, y, button=1):
self.obj.onMouseDrag(self, x, y, button)
def _onKeyDown(self, key):
self.obj.onKeyDown(self, key)
def _onKeyUp(self, key):
self.obj.onKeyUp(self, key)
def getminx(self):
return self.obj.minx+self.x
def getminy(self):
return self.obj.miny+self.y
def getmaxx(self):
return self.obj.maxx
def getmaxy(self):
return self.obj.maxy
minx = property(getminx)
miny = property(getminy)
maxx = property(getmaxx)
maxy = property(getmaxy)
def hitTest(self, x, y):
x,y = self.transformcoords(x,y)
return self.obj.hitTest(x, y)
def transformcoords(self,x,y):
x = x-self.x
y = y-self.y
return x,y
class frame:
def __reduce__(self):
badvars = (self.parent,self.group)
self.parent = None
ret = pickle.dumps(self)
self.parent, self.group = badvars
return ret
def __init__(self,parent,duplicate=None):
self.objs = []
self.currentselect=None
self.type="Group"
self.parent = parent
self.actions = ''
def add(self, obj, x, y, rot=0, scalex=1, scaley=1):
self.objs.append(framewrapper(obj, x, y, rot, scalex, scaley, self.objs))
def play(self, group, cr, currentselect,transform,rect):
if SYSTEM=="gtk":
cr.save()
cr.translate(group.x,group.y)
cr.rotate(group.rotation*math.pi/180)
cr.scale(group.xscale,group.yscale)
result = [obj.draw(cr) for obj in self.objs if ((obj.minx>=rect[0] and obj.miny>=rect[1]) or (obj.maxx<=rect[2] and obj.maxy<=rect[3]))]
if currentselect:
cr.set_source_rgb(0,0,1)
cr.rectangle(currentselect.minx-1,currentselect.miny-1,currentselect.maxx+2,currentselect.maxy+2)
cr.stroke()
cr.restore()
elif SYSTEM=="android":
global tb
tb+="cr.save()\n"
tb+="cr.translate("+str(group.x)+","+str(group.y)+")\n"
tb+="cr.rotate("+str(group.rotation*math.pi/180)+")\n"
result = [obj.draw(cr) for obj in self.objs]
if currentselect:
tb+="cr.strokeSyle = \"#0000FF\"\n"
tb+="cr.rect("+str(currentselect.minx-1)+","+str(currentselect.miny-1)+","+str(currentselect.maxx+2)+","+str(currentselect.maxy+2)+")\n"
tb+="cr.stroke()\n"
tb+="cr.restore()\n"
elif SYSTEM=="osx":
self.group = group
if USING_GL:
#cr.gsave()
#cr.rotate(group.rotation)
#cr.translate(group.x,group.y)
#cr.scale(group.xscale,group.yscale)
def dodraw(obj, cr):
obj.draw(cr, self)
result = [dodraw(obj, cr) for obj in self.objs]
if currentselect:
cr.save()
glColor3f(0,0,1)
glBegin(GL_LINES)
glVertex2f(currentselect.minx-1,cr.height-(currentselect.miny-1))
glVertex2f(currentselect.maxx+currentselect.x+2, cr.height-(currentselect.miny-1))
glVertex2f(currentselect.maxx+currentselect.x+2, cr.height-(currentselect.miny-1))
glVertex2f(currentselect.maxx+currentselect.x+2, cr.height-(currentselect.maxy+currentselect.y+2))
glVertex2f(currentselect.maxx+currentselect.x+2, cr.height-(currentselect.maxy+currentselect.y+2))
glVertex2f(currentselect.minx-1,cr.height-(currentselect.maxy+currentselect.y+2))
glVertex2f(currentselect.minx-1,cr.height-(currentselect.maxy+currentselect.y+2))
glVertex2f(currentselect.minx-1,cr.height-(currentselect.miny-1))
glEnd()
cr.restore()
print "selected", currentselect
# cr.restore()
else:
cr.gsave()
cr.rotate(group.rotation)
cr.translate(group.x,group.y)
cr.scale(group.xscale,group.yscale)
def dodraw(obj, cr):
obj.draw(cr, self)
result = [dodraw(obj, cr) for obj in self.objs]
if currentselect:
cr.gsave()
cr.newpath()
cr.pencolor = Colors.rgb(0,0,1)
cr.rect([currentselect.minx-1,currentselect.miny-1,
currentselect.maxx+currentselect.x+2,
currentselect.maxy+currentselect.y+2])
cr.stroke()
if MODE=="s":
cr.newpath()
cr.pencolor = Colors.rgb(1,1,1)
cr.fillcolor = Colors.rgb(0,0,0)
cr.rect([currentselect.minx-5,currentselect.miny-5,
currentselect.minx+5,currentselect.miny+5])
cr.rect([currentselect.maxx+currentselect.x-5,currentselect.miny-5,
currentselect.maxx+currentselect.x+5,currentselect.miny+5])
cr.rect([currentselect.maxx+currentselect.x-5,currentselect.maxy+currentselect.y-5,
currentselect.maxx+currentselect.x+5,currentselect.maxy+currentselect.y+5])
cr.rect([currentselect.minx-5,currentselect.maxy+currentselect.y-5,
currentselect.minx+5,currentselect.maxy+currentselect.y+5])
cr.fill_stroke()
cr.grestore()
cr.grestore()
elif SYSTEM=="html":
tb = ""
tb+="cr.save()\n"
tb+="cr.translate("+str(group.x)+","+str(group.y)+")\n"
tb+="cr.rotate("+str(group.rotation*math.pi/180)+")\n"
def dodraw(obj, cr):
obj.draw(cr, self)
result = [dodraw(obj, cr) for obj in self.objs]
if currentselect:
tb+="cr.strokeSyle = \"#0000FF\"\n"
tb+="cr.rect("+str(currentselect.minx-1)+","+str(currentselect.miny-1)+","+str(currentselect.maxx+2)+","+str(currentselect.maxy+2)+")\n"
tb+="cr.stroke()\n"
tb+="cr.restore()\n"
jscommunicate(tb)
def localtransform(self,x,y):
radrot = self.group.rotation*math.pi/180.0
nx = x*math.cos(-radrot)-y*math.sin(-radrot)-self.group.x
ny = x*math.sin(-radrot)+y*math.cos(-radrot)-self.group.y
return nx, ny
def revlocaltransform(self,x,y):
radrot = self.group.rotation*math.pi/180.0
nx = x*math.cos(radrot)-y*math.sin(radrot)-self.group.x
ny = x*math.sin(radrot)+y*math.cos(radrot)-self.group.y
return nx, ny
def print_sc(self):
retval = ""
if self==self.parent.frames[0]:
for i in self.objs:
if isinstance(i.obj, Sound):
retval = retval+".play "+i.obj.name+"\n"
elif i.obj.iname:
retval = retval+".put "+i.obj.iname+"="+i.name+" x="+str(i.x)+" y="+str(i.y)+" scalex="+str(i.xscale*100)+" scaley="+str(i.yscale*100)+"\n"
else:
retval = retval+".put "+i.name+" x="+str(i.x)+" y="+str(i.y)+" scalex="+str(i.xscale*100)+"% scaley="+str(i.yscale*100)+"%\n"
else:
for i in self.objs:
if isinstance(i.obj, Sound):
retval = retval+".play "+i.obj.name+"\n"
elif not i.obj in [j.obj for j in misc_funcs.lastval(self.parent.frames,self.parent.frames.index(self)).objs]:
if not hasattr(i.obj, "iname"):
i.obj.iname = None
if i.obj.iname:
retval = retval+".put "+i.obj.iname+"="+i.name+" x="+str(i.x)+" y="+str(i.y)+" scalex="+str(i.xscale*100)+"% scaley="+str(i.yscale*100)+"%\n"
else:
retval = retval+".put "+i.name+" x="+str(i.x)+" y="+str(i.y)+"scalex="+str(i.xscale*100)+"% scaley="+str(i.yscale*100)+"%\n"
else:
retval = retval+".move "+i.name+" x="+str(i.x)+" y="+str(i.y)+"\n"
retval = retval+".change "+i.name+" scalex="+str(i.xscale*100)+"% scaley="+str(i.yscale*100)+"%\n"
if not self.actions.strip()=='':
retval = retval + ".action:\n"+self.actions+"\n.end\n"
return retval
class Layer:
def setscale(self, scal):
self.xscale = scal
self.yscale = scal
def getminx(self):
return min([i.minx for i in self.currentFrame()])
def getminy(self):
return min([i.miny for i in self.currentFrame()])
def getmaxx(self):
return max([i.maxx+i.x for i in self.currentFrame()])
def getmaxy(self):
return max([i.maxy+i.y for i in self.currentFrame()])
def onMouseDown(self, self1, x, y, button=1, clicks=1):
pass
def onMouseDrag(self, self1, x, y, button=1, clicks=1):
pass
def onMouseUp(self, self1, x, y, button=1, clicks=1):
pass
def onMouseMove(self, self1, x, y, button=1):
pass
def onKeyDown(self, self1, key):
pass
def onKeyUp(self, self1, key):
pass
def getcurrentselect(self):
return self.frames[self.currentframe].currentselect
def setcurrentselect(self, val):
self.frames[self.currentframe].currentselect = val
minx = property(getminx)
miny = property(getminy)
maxx = property(getmaxx)
maxy = property(getmaxy)
scale = property(fset = setscale)
currentselect = property(getcurrentselect, setcurrentselect)
def __init__(self, *args):
# init is system-independent, oh joy
self.x=0
self.y=0
self.rotation=0
self.xscale = 1.0
self.yscale = 1.0
self.objs=[]
self.currentframe=0
self.activeframe=0 # Frame selected - not necessarily the frame displayed
self.frames=[frame(self)]
self.level = False
self.clicked = False
self.hidden = False
def parse_obj(obj):
self.objs.append(obj)
obj.x=obj.x-self.x
obj.y=obj.y-self.y
[parse_obj(obj) for obj in args]
def draw(self,cr=None,transform=None,rect=None):
if SYSTEM=="android":
global tb
rc = False
if cr:
rc = True
cr = None
self.frames[self.currentframe].play(self,cr, self.currentselect, transform,rect)
if SYSTEM=="android":
if rc:
droid.eventPost("javaevent", tb)
tb = ""
def add(self,*args):
# system-independent
def parse_obj(obj):
obj.x=obj.x-self.x
obj.y=obj.y-self.y
self.frames[self.currentframe].add(obj, obj.x, obj.y, obj.rotation,1,1)
self.objs.append(obj)
[parse_obj(obj) for obj in args]
def delete(self,*args):
for i in args:
print "#>>",i
for j in self.frames[self.currentframe].objs:
if j == i:
del self.currentFrame()[self.currentFrame().index(j)]
def add_frame(self,populate):
if self.activeframe>len(self.frames):
lastframe = len(self.frames)
for i in xrange((self.activeframe+1)-len(self.frames)):
self.frames.append(None)
if self.frames[self.activeframe]==None:
self.frames[self.activeframe]=frame(self)
for i in xrange(self.activeframe-1,-1,-1):
if self.frames[i]:
lastframe = i
break
else:
lastframe = self.activeframe
else:
lastframe = self.activeframe
self.activeframe+=1
self.frames.insert(self.activeframe,frame(self))
for i in self.frames[lastframe].objs:
i.update()
self.frames[self.activeframe].add(i.obj, i.x, i.y, i.rot)
self.currentframe = self.activeframe
def descendItem(self):
if self.currentselect.__class__.__name__=="Group" and self.level==True:
return self.frames[self.currentframe].currentselect.descendItem()
else:
return self
def currentFrame(self):
return self.frames[self.currentframe].objs
def _onMouseDown(self, x, y, button=1, clicks=1):
if self.level:
if self.currentselect and self.currentselect.level:
self.currentselect._onMouseDown(self.currentselect, x, y, button=button, clicks=clicks)
else:
if MODE in [" ", "s", "b"]:
if self.currentselect and MODE=="s":
if self.currentselect.minx-5<x<self.currentselect.minx+5:
print "hey!"
else:
for i in reversed(self.currentFrame()):
test = False
if i.hitTest(x, y):
if MODE in [" ", "s"]:
self.currentselect = i
i._onMouseDown(x, y, button=button, clicks=clicks)
test=True
break
if not test:
self.currentselect = None
else:
self.onMouseDown(self, x, y, button=button, clicks=clicks)
else:
self.onMouseDown(self, x, y, button=button, clicks=clicks)
def onMouseDown(self, self1, x, y, button=1, clicks=1):
pass
def _onMouseUp(self,x,y, button=1, clicks=1):
if self.level and MODE in [" ", "s"]:
if self.currentselect:
self.currentselect._onMouseUp(x, y, button=1)
else:
self.onMouseUp(self, x, y, button=button)
def onMouseUp(self, self1, x, y, button=1, clicks=1):
pass
def _onMouseMove(self,x,y, button=1):
if self.level and MODE in [" ", "s"]:
if self.currentselect:
self.currentselect._onMouseMove(x, y, button=button)
else:
self.onMouseMove(self, x, y)
def onMouseMove(self, self1, x, y, button=1):
pass
def _onMouseDrag(self, x, y, button=1):
if self.level and MODE in [" ", "s"]:
if self.currentselect:
self.currentselect._onMouseDrag(x, y, button=button)
else:
self.onMouseDrag(self, x, y, button=button)
def onMouseDrag(self, self1, x, y, button=1):
pass
def _onKeyDown(self, key):
if self.level and MODE in [" ", "s", "t"]:
if self.currentselect:
self.currentselect._onKeyDown(key)
else:
self.onKeyDown(self, key)
def onKeyDown(self, self1, key):
pass
def _onKeyUp(self, key):
if self.level and MODE in [" ", "s", "t"]:
if self.currentselect:
self.currentselect._onKeyUp(key)
else:
self.onKeyUp(self, key)
def onKeyUp(self, self1, key):
pass
def print_sc(self,defs=True,frams=True):
retval = ""
if defs:
for i in self.objs:
if i.type=="Group":
retval+=".sprite "+i.name+"\n"+i.print_sc()+".end\n"
elif i.type=="Shape":
retval+=".outline "+i.name+"outline:\n"
retval+=" ".join([" ".join([str(x) for x in a]) for a in i.shapedata])+"\n.end\n"
if i.filled:
retval+=".filled "+i.name+" outline="+i.name+"outline fill="+i.fillcolor.rgb+" color="+i.linecolor.rgb+"\n"
else:
retval+=".filled "+i.name+" outline="+i.name+"outline fill=#00000000 color="+i.linecolor.rgb+"\n"
elif i.type=="Image":
retval+=".png "+i.name+" \""+i.path+"\"\n"
if frams:
for i in self.frames:
print i
if i:
retval+=".frame "+str(self.frames.index(i)+1)+"\n"+i.print_sc()
return retval
class Group (object):
def setscale(self, scal):
self.xscale = scal
self.yscale = scal
def getal(self):
return self.layers[self._al]
def setal(self,al):
self._al = al
def getlevel(self):
return self.activelayer.level
def setlevel(self,lev):
self.activelayer.level = lev
def getminx(self):
return min([i.minx for i in self.layers])
def getminy(self):
return min([i.miny for i in self.layers])
def getmaxx(self):
return max([i.maxx for i in self.layers])
def getmaxy(self):
return max([i.maxy for i in self.layers])
def onMouseDown(self, self1, x, y, button=1, clicks=1):
pass
def onMouseDrag(self, self1, x, y, button=1, clicks=1):
pass
def onMouseUp(self, self1, x, y, button=1, clicks=1):
pass
def onMouseMove(self, self1, x, y, button=1, clicks=1):
pass
def getactiveframe(self):
return self.activelayer.activeframe
def setactiveframe(self, frame):
print self.activelayer.frames
if frame<len(self.activelayer.frames) and self.activelayer.frames[frame]:
self.activelayer.currentframe = frame
self.activelayer.activeframe = frame
def getcurrentframe(self):
return self.activelayer.activeframe
def setcurrentframe(self, frame):
print self.activelayer.frames
if frame<len(self.activelayer.frames) and self.activelayer.frames[frame]:
self.activelayer.currentframe = frame
self.activelayer.activeframe = frame
def getobjs(self):
return [item for sublist in self.layers for item in sublist.objs]
minx = property(getminx)
miny = property(getminy)
maxx = property(getmaxx)
maxy = property(getmaxy)
activelayer = property(getal,setal)
activeframe = property(getactiveframe, setactiveframe)
currentframe = property(getcurrentframe, setcurrentframe)
level = property(getlevel, setlevel)
scale = property(fset = setscale)
objs = property(getobjs)
def __init__(self, *args, **kwargs):
if not 'skipl' in kwargs:
global Library
Library.append(self)
self.layers = [Layer(*args)]
self._al = 0
self.clicked = False
self.x = 0
self.y = 0
self.rotation = 0
self.xscale = 1
self.yscale = 1
self.type = "Group"
self.startx = 0
self.starty = 0
self.cx = 0
self.cy = 0
self.dragging = False
self.selecting = False
self.tempgroup = None
self.is_mc = False
self.name = "g"+str(int(random.random()*10000))+str(SITER)
if "onload" in kwargs:
kwargs["onload"](self)
def draw(self,cr=None,transform=None,rect=None):
if self.is_mc and self.level:
cr.fillcolor = Color([1,1,1,0.5]).pygui
cr.fill_rect([0,0,1000,1000])
for i in self.layers:
if not i.hidden:
i.x = self.x
i.y = self.y
i.rotation = self.rotation
i.xscale = self.xscale
i.yscale = self.yscale
i.draw(cr,rect=rect)
if self.dragging and self.selecting and MODE in (" ", "s"):
if SYSTEM=="osx":
cr.newpath()
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]])
def add(self, *args):
self.activelayer.add(*args)
def add_frame(self, populate):
self.activelayer.add_frame(populate)
def add_layer(self, index):
self.layers.insert(index+1,Layer())
self.activelayer = index+1
self.activelayer.level = True
def delete_layer(self, index):
del self.layers[index]
while self._al>=0:
try:
dum = self.activelayer
break
except IndexError:
self._al-=1
if self._al<0:
self.add_layer(-1)
def descendItem(self):
if self.activelayer.currentselect.__class__.__name__=="Group" and self.level==True:
return self.frames[self.currentframe].currentselect.descendItem()
else:
return self
self.activelayer.descendItem()
def currentFrame(self):
return self.activelayer.currentFrame()
def localtransform(self,x,y):
radrot = self.rotation*math.pi/180.0
nx = x*math.cos(-radrot)-y*math.sin(-radrot)-self.x
ny = x*math.sin(-radrot)+y*math.cos(-radrot)-self.y
return nx, ny
def onLoad(self, self1):
pass
def _onMouseDown(self, x, y, button=1, clicks=1):
x, y = self.localtransform(x, y)
if self.level:
if self.activelayer.currentselect and self.activelayer.currentselect.level:
self.activelayer.currentselect._onMouseDown(self.activelayer.currentselect, x, y)
else:
if MODE in [" ", "s", "b"]:
if CURRENTTEXT:
CURRENTTEXT.editing = False
if self.activelayer.currentselect and MODE=="s":
global SCALING
if (self.activelayer.currentselect.minx-5<x<self.activelayer.currentselect.minx+5 and \
self.activelayer.currentselect.miny-5<y<self.activelayer.currentselect.miny+5) or \
(self.activelayer.currentselect.minx-5<x<self.activelayer.currentselect.minx+5 and \
self.activelayer.currentselect.miny+self.activelayer.currentselect.maxy-5<y<self.activelayer.currentselect.miny+self.activelayer.currentselect.maxy+5) or \
(self.activelayer.currentselect.minx+self.activelayer.currentselect.maxx-5<x<self.activelayer.currentselect.minx+self.activelayer.currentselect.maxx+5 and \
self.activelayer.currentselect.miny+self.activelayer.currentselect.maxy-5<y<self.activelayer.currentselect.miny+self.activelayer.currentselect.maxy+5) or \
(self.activelayer.currentselect.minx+self.activelayer.currentselect.maxx-5<x<self.activelayer.currentselect.minx+self.activelayer.currentselect.maxx+5 and \
self.activelayer.currentselect.miny-5<y<self.activelayer.currentselect.miny+5):
SCALING = True
self.activelayer.currentselect._onMouseDown(x, y, button=button, clicks=clicks)
else:
test = False
for i in reversed(self.currentFrame()):
if i.hitTest(x, y):
if MODE in [" ", "s"]:
self.activelayer.currentselect = i
test=True
print 'onmousedowning'
i._onMouseDown(x, y, button=button, clicks=clicks)
break
if not test:
if self.tempgroup:
del self.currentFrame()[[i.obj for i in self.currentFrame()].index(self.tempgroup)]
[self.currentFrame().append(i) for i in self.tempgroup.split()]
self.tempgroup = None
self.activelayer.currentselect = None
self.startx, self.starty = x, y
self.selecting = True
else:
self.onMouseDown(self, x, y, button=button, clicks=clicks)
else:
print "HEYY"
self.onMouseDown(self, x, y, button=button, clicks=clicks)
def onMouseDown(self, self1, x, y, button=1, clicks=1):
pass
def _onMouseUp(self,x,y, button=1, clicks=1):
global SCALING
SCALING = False
self.dragging = False
self.selecting = False
x, y = self.localtransform(x, y)
if self.activelayer.level and MODE in [" ", "s"]:
if self.activelayer.currentselect:
self.activelayer.currentselect._onMouseUp(x, y, button=button, clicks=clicks)
elif abs(self.startx-x)>4 or abs(self.starty-y)>4:
objs = []
for i in reversed(self.currentFrame()):
if self.startx<i.x+i.minx<x or self.startx<i.x+i.maxx<x:
if self.starty<i.y+i.miny<y or self.starty<i.y+i.maxy<y:
objs.append(i)
del self.currentFrame()[self.currentFrame().index(i)]
if objs:
tgroup = TemporaryGroup(skipl=True)
[tgroup.add(i.obj) for i in reversed(objs)]
self.add(tgroup)
self.activelayer.currentselect = tgroup
self.tempgroup = tgroup
print [i.obj for i in self.currentFrame()]
else:
self.onMouseUp(self, x, y, button=button, clicks=clicks)
def onMouseUp(self, self1, x, y, button=1, clicks=1):
pass
def _onMouseMove(self,x,y,button=1,clicks=1):
x, y = self.localtransform(x, y)
if self.activelayer.level and MODE in [" ", "s"]:
if self.activelayer.currentselect:
self.activelayer.currentselect._onMouseMove(x, y, button=button)
else:
self.onMouseMove(self, x, y, button=button)
def onMouseMove(self, self1, x, y, button=1, clicks=1):
pass
def _onMouseDrag(self, x, y, button=1, clicks=1):
x, y = self.localtransform(x, y)
self.cx, self.cy = x, y
self.dragging = True
if self.activelayer.level and MODE in [" ", "s"]:
if self.activelayer.currentselect:
self.activelayer.currentselect._onMouseDrag(x, y, button=button)
else:
self.onMouseDrag(self, x, y, button=button)
def onMouseDrag(self, self1, x, y, button=1, clicks=1):
pass
def _onKeyDown(self, key):
if self.activelayer.level and MODE in [" ", "s", "t"]:
if self.activelayer.currentselect:
self.activelayer.currentselect._onKeyDown(key)
else:
self.onKeyDown(self, key)
def onKeyDown(self, self1, key):
pass
def _onKeyUp(self, key):
if self.activelayer.level and MODE in [" ", "s", "t"]:
if self.activelayer.currentselect:
self.activelayer.currentselect._onKeyUp(key)
else:
self.onKeyUp(self, key)
def onKeyUp(self, self1, key):
pass
def maxframe(self):
frame = 0
for i in self.layers:
frame = max(frame, len(i.frames))
return frame
def hitTest(self,x,y):
for i in self.layers:
for j in i.frames[0].objs:
if j.hitTest(x, y):
return True
return False
def print_sc(self):
retval = ""
#for i in self.layers:
# retval+=i.print_sc(True, False)
if not self.name=="_root":
retval+=".sprite "+self.name+"\n"
for i in xrange(self.maxframe()):
for j in self.layers:
if j.frames[i]:
retval+=".frame "+str(i+1)+"\n"
retval+=j.frames[i].print_sc()
if not self.name=="_root":
retval+=".end\n"
return retval
def print_html(self):
retval = ""
if not self.name=="_root":
retval = retval + "var "+self.name+" = new MovieClip();\n"
for i in self.layers:
pass
#retval+=i.print_html(True,False)
'''for i in xrange(self.maxframe()):
for j in self.layers:
if j.frames[i]:
retval+=".frame "+str(i+1)+"\n"
retval+=j.frames[i].print_html()'''
print self.objs
for i in self.objs:
retval += self.name+"."+i.name.replace(".","_")+" = "+i.name.replace(".","_")+";\n"
for i in range(len(self.layers)):
for j in xrange(self.maxframe()):
if self.layers[i].frames[j]:
retval += self.name+"._layers["+str(i)+"]._frames["+str(j)+"] = new Frame ();\n"
for k in self.layers[i].frames[j].objs:
# if isinstance(k.obj, Sound):
# retval += self.name+"._layers["+str(i)+"]._frames["+str(j)+"]."+k.obj.name.replace(".","_")+".start();\n"
# # retval += self.name+"."+k.obj.name.replace(".","_")+".start();\n"
# else:
retval += self.name+"._layers["+str(i)+"]._frames["+str(j)+"]."+k.name.replace('.',"_")+" = {};\n"
retval += self.name+"._layers["+str(i)+"]._frames["+str(j)+"]."+k.name.replace('.',"_")+"._x = "+str(k.x)+";\n"
retval += self.name+"._layers["+str(i)+"]._frames["+str(j)+"]."+k.name.replace('.',"_")+"._y = "+str(k.y)+";\n"
retval += self.name+"._layers["+str(i)+"]._frames["+str(j)+"]."+k.name.replace('.',"_")+"._rotation = "+str(k.rot)+";\n"
retval += self.name+"._layers["+str(i)+"]._frames["+str(j)+"]."+k.name.replace('.',"_")+"._xscale = "+str(k.xscale)+";\n"
retval += self.name+"._layers["+str(i)+"]._frames["+str(j)+"]."+k.name.replace('.',"_")+"._yscale = "+str(k.yscale)+";\n"
retval += self.name+"._layers["+str(i)+"]._frames["+str(j)+"].actions = \""+self.layers[i].frames[j].actions.replace("\n"," ").replace("\\","\\\\").replace("\"","\\\"")+"\"\n"
return retval
class TemporaryGroup(Group):
"""Created when selecting multiple items, for ease of use."""
def __init__(self, *args, **kwargs):
(TemporaryGroup, self).__init__(*args, **kwargs)
# def draw(self, cr=None, transform=None, rect=None):
# super(TemporaryGroup, self).draw(cr, transform, rect)
# print self.x, self.activelayer.x
# pass
def split(self):
for i in self.currentFrame():
i.x = i.x+self.x
i.y = i.y+self.y
return self.currentFrame()
pass
def onMouseDown(self, self1, x, y, button=1, clicks=1):
print "Hihihihihi"
if self1.hitTest(x, y):
self1.clicked = True
self1.initx,self1.inity = x-self1.x, y-self1.y
def onMouseDrag(self, self1, x, y, button=1, clicks=1):
if MODE==" ":
self1.x = x-self1.initx
self1.y = y-self1.inity
elif MODE=="s":
if SCALING:
# Not working yet.
if self1.initx>self1.maxx/2:
self1.xscale = (x-self1.x)/self1.maxx
else:
self1.xscale = (2*self1.maxx+self1.x-(x-self1.initx)-x)/self1.maxx
self1.x = x
if self1.inity>self1.maxy/2:
self1.yscale = (y-self1.y)/self1.maxy
else:
# 3 times?? Why??
self1.yscale = (3*self1.maxy+self1.y-(y-self1.inity)-y)/self1.maxy
self1.y = y
def onMouseUp(self, self1, x, y, button=1, clicks=1):
self.clicked = False
def onKeyDown(self, self1, key):
if key in ("delete", "backspace"):
del self1.parent[self1.parent.index(self1)] # Need to clean up deletion
elif key in [" ", "s", "r", "e", "b", "p"]:
svlgui.MODE=key
svlgui.set_cursor({" ":"arrow","s":"arrow","r":"crosshair","e":"crosshair",
"b":"arrow","p":"arrow"}[key], MainWindow.stage)
misc_funcs.update_tooloptions()
elif key=="F6":
add_keyframe()
elif key=="F8":
convert_to_symbol()
elif key=="left_arrow":
self1.x-=1
elif key=="right_arrow":
self1.x+=1
elif key=="up_arrow":
self1.y-=1
elif key=="down_arrow":
self1.y+=1
def set_cursor(curs, widget=None):
if SYSTEM == "osx":
cursdict = {"arrow":StdCursors.arrow, "ibeam":StdCursors.ibeam,
"crosshair":StdCursors.crosshair, "fist":StdCursors.fist,
"hand":StdCursors.hand, "finger":StdCursors.finger,
"invisible":StdCursors.invisible, "text":StdCursors.ibeam}
if curs in cursdict:
if widget:
widget._int().cursor = cursdict[curs]
else:
app.cursor = cursdict[curs]
else:
print "Sorry, I don't have that cursor."
def alert(text,critical=False,confirm=False,async=False):
'''Launches an alert window with a given text.
If critical is True, closing the alert terminates SWIFT.'''
if SYSTEM=="gtk":
def abutton_press_event(widget, event):
#Close when "Ok" is pressed
alert.destroy()
def on_destroy(event):
if critical:
#if this is a critical alert, such as when another instrance of SWIFT is already running
gtk.main_quit()
alert = gtk.Window(type=gtk.WINDOW_TOPLEVEL) # make a new window for the alert
alert.set_position(gtk.WIN_POS_CENTER) # put it in the center of the screen
alert.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG) # tell the WM that it is a dialog
alert.set_destroy_with_parent(True) # if someone closes SWIFT, we want the alert to close too
alert.set_modal(True) # alert should block input to SWIFT until acknowledged
alert.set_title("Alert") # call it "Alert"
alert.set_size_request(250, 100) # make it 250x100
avbox = vbox = gtk.VBox(False, 0) # create a vertical box container
alert.add(avbox) # add said container to the alert
alabel=gtk.Label(text) # make a label to hold the text
alabel.set_size_request(240,-1) # make it slightly narrower than the parent window
alabel.set_line_wrap(True) # we want the text to word wrap
alabel.set_justify(gtk.JUSTIFY_CENTER) # center the text
avbox.pack_start(alabel, False, True, 0) # put it at the start of the vbox
alabel.show() # make it visible
abutton = gtk.Button("OK") # new button with text "OK"
abutton.set_use_stock(True) # it is a stock button provided by GTK
abutton.set_size_request(50, -1) # we don't want it as wide as the whole alert
abutton.set_events(gtk.gdk.ALL_EVENTS_MASK); # capture clicks, keyboard, anything
abutton.connect("button_press_event", abutton_press_event) # but only listen to the clicks
alert.connect("destroy", on_destroy) # close alert when alert is closed
abutton.show() # make button visible
ahbox = gtk.HBox(False, 10) # make a new hbox
ahbox.pack_start(abutton, True, False, 0) # put the button in it, but don't make it expand
avbox.pack_start(ahbox, True, False, 0) # put the hbox in the vbox
ahbox.show() # make it visible
avbox.show() # make the vbox visible
alert.show() # make the alert itself visible
elif SYSTEM=="osx":
#Much simpler. :)
if critical:
Alerts.stop_alert(text) # stop_alert is a critical error alert
sys.exit(0) # Exit to OS. Sometimes we can't recover an error.
else:
if confirm:
return Alerts.confirm(text)
else:
if async:
a = ModalDialog()
a.place(OSXLabel(text=text),left=0,top=0,right=0,bottom=0,sticky="nesw")
a.show()
a.present()
return a
else:
Alerts.note_alert(text) # note_alert is a general alert, i.e. "I'm a computer."
elif SYSTEM=="html":
jscommunicate("alert("+text+")")
if critical:
# reloading the page is equivalent to force-quitting, right?
jscommunicate("window.location.reload()")
def file_dialog(mode="open",default=None,types=None,multiple=False,name=None):
if SYSTEM=="osx":
if types:
ntypes = []
mactypes = {"txt":'TEXT', "pdf":'PDF ',"mov":'MooV',"mpg":'MPG ',"mp2":'MPG2',
"mp4":'M4V ',"m4v":'M4V ',"mp3":'Mp3 ',"gif":'GIFf',"png":'PNGf',"jpg":'JPEG',
"bmp":'BMPf',"tiff":'TIFF',"psd":'8BPS',"mid":'Midi',"rtf":'RTF ',"wav":'WAVE',
"aif":'AIFF',"ttf":'tfil',"swf":'SWFL'}
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
if mode=="open":
if multiple:
return FileDialogs.request_old_files(default_dir=default,file_types=types)
else:
return FileDialogs.request_old_file(default_dir=default,file_types=types)
elif mode=="save":
return FileDialogs.request_new_file(default_name=name,default_dir=default,file_type=types)
def execute(command):
rv = os.system(command.replace("/",sep))
if SYSTEM == "osx":
if rv==0:
return True
else:
return False
class OverlayWindow:
if SYSTEM=="gtk":
def expose (widget, event, startime=time.time()):
cr = widget.window.cairo_create()
# Sets the operator to clear which deletes everything below where an object is drawn
cr.set_operator(cairo.OPERATOR_CLEAR)
# Makes the mask fill the entire window
cr.rectangle(0.0, 0.0, *widget.get_size())
# Deletes everything in the window (since the compositing operator is clear and mask fills the entire window
cr.fill()
# Set the compositing operator back to the default
cr.set_operator(cairo.OPERATOR_OVER)
widget.present()
# Clear background to transparent black
cr.set_source_rgba(0.0,0.0,0.0,2.0-(time.time()-startime))
cr.paint()
image = media_path+"media/logo-transparent.png"
surface = cairo.ImageSurface.create_from_png(image)
pat = cairo.SurfacePattern(surface)
cr.set_source(pat)
cr.paint_with_alpha(2.0-(time.time()-startime))
#return True
win = gtk.Window()
win.set_decorated(False)
win.set_modal(True)
# Makes the window paintable, so we can draw directly on it
win.set_app_paintable(True)
win.set_size_request(512, 512)
win.set_position(gtk.WIN_POS_CENTER)
# This sets the windows colormap, so it supports transparency.
# This will only work if the wm support alpha channel
screen = win.get_screen()
rgba = screen.get_rgba_colormap()
win.set_colormap(rgba)
win.connect('expose-event', expose)
win.show()
win.present()
gobject.timeout_add(50, expose, win, 'fade-event', time.time())
gobject.timeout_add(2000, win.destroy)
class ColorSelectionWindow:
def __init__(self,var,dispgrp=None, dcanv=None):
if SYSTEM=="gtk":
win = gtk.Window()
win.set_size_request(320,208)
win.set_decorated(False)
darea = gtk.DrawingArea()
darea.set_size_request(320,208)
win.add(darea)
win.show_all()
win.add_events(gtk.gdk.EXPOSURE_MASK
| gtk.gdk.LEAVE_NOTIFY_MASK
| gtk.gdk.BUTTON_PRESS_MASK
| gtk.gdk.BUTTON_RELEASE_MASK
| gtk.gdk.KEY_PRESS_MASK
| gtk.gdk.POINTER_MOTION_MASK
| gtk.gdk.POINTER_MOTION_HINT_MASK)
def expose_event(widget, event):
x,y,w,h = widget.allocation
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, w,h)
cr = cairo.Context(surface)
cra = widget.window.cairo_create()
cr.set_source_rgb(0.5, 0.5, 0.5)
cr.paint()
for i in xrange(21):
for j in xrange(len(colors.colorArray(i))):
cr.rectangle(i*16,j*16,15,15)
r,g,b = colors.colorArray(i)[j]
cr.set_source_rgb(r,g,b)
cr.fill()
cra.set_source_surface(surface)
cra.paint()
def close(widget, event, dispshape, dcanv):
global LINECOLOR,FILLCOLOR
if var=="line":
LINECOLOR = Color(colors.colorArray(int(event.x)/16)[int(event.y)/16])
elif var=="fill":
FILLCOLOR = Color(colors.colorArray(int(event.x)/16)[int(event.y)/16])
dispgrp.frames[0].objs[2].fillcolor = LINECOLOR if var=="line" else FILLCOLOR
dcanv.draw()
widget.destroy()
darea.connect("expose-event",expose_event)
win.connect("button-press-event", close, dispgrp, dcanv)
win.set_modal(True)
win.present()
elif SYSTEM=="osx":
win = ModalDialog(width=336,height=208,resizable=False)
def onClickRectFill(self,x,y,button=None,clicks=None):
global FILLCOLOR
FILLCOLOR = Color(colors.colorArray(int(x/16))[int(y/16)])
if root.descendItem().activelayer.currentselect:
if not (root.descendItem().activelayer.currentselect.fillcolor.val == FILLCOLOR.val and root.descendItem().activelayer.currentselect.filled==True):
undo_stack.append(edit("fill", root.descendItem().activelayer.currentselect, \
{"filled":root.descendItem().activelayer.currentselect.filled, \
"fillcolor":root.descendItem().activelayer.currentselect.fillcolor},
{"filled":True, "fillcolor":svlgui.FILLCOLOR}))
clear(redo_stack)
root.descendItem().activelayer.currentselect.fillcolor = FILLCOLOR
root.descendItem().activelayer.currentselect.filled = True
root.descendItem().activelayer.currentselect.update()
self.window.dismiss()
raise ObjectDeletedError
def onClickRectLine(self,x,y,button=None,clicks=None):
global LINECOLOR
LINECOLOR = Color(colors.colorArray(int(x/16))[int(y/16)])
if root.descendItem().activelayer.currentselect:
root.descendItem().activelayer.currentselect.linecolor = LINECOLOR
root.descendItem().activelayer.currentselect.update()
self.window.dismiss()
raise ObjectDeletedError
canvas = Canvas(336,208)
canvas._int().scrolling = ''
group = Group(skipl=True)
def dummy(*args):
pass
group._onMouseMove = dummy
canvas.add(group,0,0)
im = Image(media_path+"media/colors.png",skipl=True)
group.add(im)
group.window = win
group.canvas = canvas
if var=="fill":
group.onMouseDown = onClickRectFill
if var=="line":
group.onMouseDown = onClickRectLine
win.place(canvas._int(),left=0,top=0,right=0,bottom=0,sticky="news",scrolling="")
win.present()
class PreferencesWindow:
def __init__(self):
if SYSTEM=="osx":
win = ModalDialog(closable=True,width=500,height=500)
self.win.title = "Preferences"
frame = Frame()
win.place(frame._int(), left=0, top=0, right=0, bottom=0, sticky="nsew")
label = Label("Path to Flash Debugger: ")
frame.layout_self([label,0,None,0,None,"nw",""])
win.present()
class SizeWindow:
def __init__(self):
if SYSTEM=="osx":
self.width = WIDTH
self.height = HEIGHT
self.win = ModalDialog(closable=True,width=160,height=70)
self.win.title = "Dimensions"
frame = Frame()
self.win.place(frame._int(), left=0, top=0, right=0, bottom=0, sticky="nsew")
wlabel = Label("Width: ")
hlabel = Label("Height: ")
self.wentry = TextEntry(str(WIDTH))
self.hentry = TextEntry(str(HEIGHT))
b1 = DefaultButton()
b1.action = self.set_size
b2 = CancelButton()
b2.action = self.restore_size
frame.layout_self( [wlabel,0,None,0,None,"nw",""],
[self.wentry,wlabel._int(),None,0,None,"nw",""],
[hlabel,0,None,self.wentry._int(),None,"nw",""],
[self.hentry,hlabel._int(),None,self.wentry._int(),None,"nw",""],
[Widget(b2),0,None,None,0,'nw',''],
[Widget(b1),None,0,None,0,'nw',''])
self.win.present()
def set_size(self):
global WIDTH, HEIGHT
WIDTH = int(self.wentry.text)
HEIGHT = int(self.hentry.text)
self.win.ok()
def restore_size(self):
global WIDTH, HEIGHT
WIDTH, HEIGHT = self.width, self.height
self.win.cancel()
class PublishSettingsWindow:
def __init__(self):
if SYSTEM=="osx":
self.win = ModalDialog(closable=True,width=400,height=300)
self.win.title = "Publish Settings"
frame = Frame()
self.win.place(frame._int(), left=0, top=0, right=0, bottom=0, sticky="nsew")
plabel = Label("Settings-publish")
elabel = Label("Export: ")
self.c1 = OSXCheckBox("SWF")
self.c2 = OSXCheckBox("HTML5")
self.c3 = OSXCheckBox("Base HTML file")
self.c3.action = self.deactivate4
self.c4 = OSXCheckBox("Setup fallback content")
self.c4.action = self.activate3
swlabel = Label("SWF:")
htlabel = Label("HTML5:")
self.impack = OSXCheckBox("Pack Images (Not implemented yet!)")
self.impack.action = self.activate3
b1 = DefaultButton()
b1.action = self.confirm
b2 = CancelButton()
frame.layout_self( [plabel,5,None,5,None,"nw",""],
[elabel,5,None,plabel._int(),None,"nw",""],
[Widget(self.c1),16,None,elabel._int(),None,"nw",""],
[Widget(self.c2),self.c1+16,None,elabel._int(),None,"nw",""],
[Widget(self.c3),self.c2+16,None,elabel._int(),None,"nw",""],
[Widget(self.c4),self.c2+32,None,self.c3,None,"nw",""],
[swlabel, 5, None, self.c4, None, "nw", ""],
[htlabel, 5, None, swlabel._int(), None, "nw", ""],
[Widget(self.impack), 16, None, htlabel._int(), None, "nw", ""],
[Widget(b2),5,None,None,-5,'nw',''],
[Widget(b1),None,-5,None,-5,'nw',''])
self.win.present()
def activate2(self):
self.c2.set_value(self.c2.value or self.impack.value)
def activate3(self):
self.c3.set_value(self.c3.value or self.c4.value)
def deactivate4(self):
if self.c3.value==False:
self.c4.set_value(False)
def confirm(self):
global EXPORT_OPTIONS
EXPORT_OPTIONS = {"swf":self.c1.value, "html5":self.c2.value, "basehtml":self.c3.value,
"fallback":self.c4.value,"pack":self.impack.value}
self.win.ok()
class ConvertToSymbolWindow:
def __init__(self,root,onMouseDown):
self.root = root
self.onMouseDown = onMouseDown
if SYSTEM=="osx":
self.win = ModalDialog(closable=True,width=400,height=150)
self.win.title = "Convert to symbol"
frame = Frame()
self.win.place(frame._int(), left=0, top=0, right=0, bottom=0, sticky="nsew")
nlabel = Label("Name: ")
self.ntry = TextEntry("Symbol 1") #TODO: dynamically generate this
self.ntry.set_action(self.confirm)
tlabel = Label("Type: ")
tgroup = RadioGroup("Movie Clip", "Button", "Group")
b1 = DefaultButton()
b1.action = self.confirm
b2 = CancelButton()
frame.layout_self( [nlabel,5,None,5,None,"nw",""],
[self.ntry, nlabel._int()+5,-5,5,None,'new','h'],
[tlabel,5,None,self.ntry._int(),None,'nw',''],
[tgroup[0],32,None,tlabel._int(),None,'nw',''],
[tgroup[1],32,None,tgroup[0]._int(),None,'nw',''],
[tgroup[2],32,None,tgroup[1]._int(),None,'nw',''],
[Widget(b2),5,None,None,-5,'nw',''],
[Widget(b1),None,-5,None,-5,'nw',''])
self.win.present()
def settype(self,tgroup):
self.type = tgroup.value
def confirm(self):
symbol = Group()
symbol.add(self.root.descendItem().activelayer.currentselect.obj)
symbol.name = self.ntry.text
symbol.is_mc = True
self.root.descendItem().activelayer.delete(self.root.descendItem().activelayer.currentselect)
print self.root.descendItem().activelayer.currentFrame()
self.root.descendItem().activelayer.add(symbol)
symbol.onMouseDown = self.onMouseDown
self.win.ok()
class FramesCanvas(Canvas):
def __init__(self,w,h):
Canvas.__init__(self,w,h)
self.pointer = 1
self.x = None
if SYSTEM == 'osx':
self.canvas.draw = self._draw
self.canvas.mouse_down = self.mouse_down
self.canvas.mouse_drag = self.mouse_drag
self.canvas.mouse_up = self.mouse_up
self.ackfr = GUI.Image(file = media_path+"media/keyframe_active.png")
self.inackfr = GUI.Image(file = media_path+"media/keyframe_inactive.png")
self.acfr = GUI.Image(file = media_path+"media/frame_active_tween.png")
self.inacfr = GUI.Image(file = media_path+"media/frame_inactive_tween.png")
def _draw(self,cr,update_rect):
try:
for k in xrange(len(self.root.descendItem().layers)):
FRAMES = self.root.descendItem().layers[k].frames
for i in xrange(len(FRAMES)):
cr.gsave()
#cr.translate(i*16,k*32)
if FRAMES[i]:
if self.root.descendItem().currentframe == i:
src_rect = self.ackfr.bounds
src_rect = [0,0,(16)*(self.pointer%17),32]
dst_rect = [i*16, k*32, 16+i*16, 32+k*32]
# print dst_rect
self.ackfr.draw(cr, src_rect, dst_rect)
else:
src_rect = self.inackfr.bounds
dst_rect = [i*16, k*32, 16+i*16, 32+k*32]
self.inackfr.draw(cr, src_rect, dst_rect)
else:
if self.root.descendItem() == i:
src_rect = self.acfr.bounds
dst_rect = [i*16, k*32, 16+i*16, 32+k*32]
self.acfr.draw(cr, src_rect, dst_rect)
else:
src_rect = self.inacfr.bounds
dst_rect = [i*16, k*32, 16+i*16, 32+k*32]
self.inacfr.draw(cr, src_rect, dst_rect)
cr.grestore()
for i in xrange(len(FRAMES)):
if FRAMES[i]:
try:
cr.gsave()
cr.translate(i*16,0)
sounds = [i.obj for i in FRAMES[i].objs if isinstance(i.obj, Sound)]
[i.draw_frame(cr, None) for i in sounds]
cr.grestore()
except:
traceback.print_exc()
# print max(len(FRAMES),int(update_rect[0]/16-1)),int(update_rect[2]/16+1)
for i in xrange(max(len(FRAMES),int(update_rect[0]/16-1)),int(update_rect[2]/16+1)):
cr.newpath()
cr.rect([i*16,k*32,i*16+16,k*32+32])
if self.root.descendItem().activeframe==i:
cr.fillcolor = Color([0.5,0.5,0.5]).pygui
cr.fill()
elif i%5==0:
cr.fillcolor = Color([0.8,0.8,0.8]).pygui
cr.fill()
# print i
else:
cr.fillcolor = Color([1.0,1.0,1.0]).pygui
cr.fill()
cr.newpath()
cr.fillcolor = Color([0.1,0.1,0.1]).pygui
cr.rect([i*16+15,k*32,i*16+16,k*32+32])
cr.fill()
if self.x:
src_rect = [0,0,16,32]
dst_rect = [self.x-8, 0, self.x+8, 32]
self.ackfr.draw(cr,src_rect,dst_rect)
except:
traceback.print_exc()
def mouse_down(self, event):
x, y = event.position
clicks = event.num_clicks
self.onMouseDown(self,x, y, clicks)
self.canvas.invalidate_rect([0,0,self.canvas.extent[0],self.canvas.extent[1]])
def mouse_drag(self, event):
x, y = event.position
self.onMouseDrag(self,x, y)
self.canvas.invalidate_rect([0,0,self.canvas.extent[0],self.canvas.extent[1]])
def mouse_up(self, event):
x, y = event.position
self.onMouseUp(self,x, y)
self.canvas.invalidate_rect([0,0,self.canvas.extent[0],self.canvas.extent[1]])
def onMouseDown(self,self1,x, y, button=1, clicks=1):
pass
def onMouseDrag(self, self1, x, y, button=1, clicks=1):
pass
def onMouseUp(self, self1, x, y, button=1, clicks=1):
pass
def main():
#Executes the main loop for whatever GUI is running
if SYSTEM=="gtk":
gtk.main()
elif SYSTEM=="osx":
global app
app.menus = menus
app.run()
elif SYSTEM=="html":
print __windowlist__[0].window
pass
elif SYSTEM=="pyglet":
pyglet.app.run()
def quit():
#Self-descriptive
FILE.close()
if SYSTEM=="gtk":
gtk.main_quit()
elif SYSTEM=="android":
sys.exit(0)
def jscommunicate(string):
pass
def jsdefine(func, args, body):
global jsdefs, jsfunctions
if not func in jsdefs:
jsfunctions = jsfunctions+"function "+func+args+" {\n"+body+"\n};\n"
jsdefs.append(func)