Files
@ 990a9474d0e7
Branch filter:
Location: light9/flax/tracker
990a9474d0e7
5.6 KiB
text/plain
early cue stuff. the CueList will supply the CueFader with the cues to
early cue stuff. the CueList will supply the CueFader with the cues to
work with, and will do crossfading sooner or later. the format of cues
is still very open. cuelist1 is a bogus cuelist for testing.
early cue stuff. the CueList will supply the CueFader with the cues to
work with, and will do crossfading sooner or later. the format of cues
is still very open. cuelist1 is a bogus cuelist for testing.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | #!/usr/bin/python
from __future__ import division
from skim.zooming import Zooming,Pair
from math import sqrt,sin,cos
from pygame.rect import Rect
import Tkinter as tk
class Field:
"""one light has a field of influence. for any point on the
canvas, you can ask this field how strong it is. """
center=Pair(0,0)
falloff=0
def setcenter(self,x,y):
self.center=Pair(x,y)
def setfalloff(self,dist):
"""linear falloff from 1 at center, to 0 at dist pixels away
from center"""
self.falloff=dist
def getdistforintensity(self,intens):
"""returns the distance you'd have to be for the given intensity (0..1)"""
return (1-intens)*self.falloff
def calc(self,x,y):
"""returns field strength at point x,y"""
dist=sqrt( (x-self.center.x)**2 + (y-self.center.y)**2 )
return max(0,(self.falloff-dist)/self.falloff)
class FieldSet:
"""group of fields. persistent."""
fields=None # lightname : Field
def __init__(self):
self.fields={}
def loadfromfile(self,f):
for line in f:
try:
col=line.index(':')
newfield=Field()
name=line[:col]
params={}
for param in line[col+1:].split():
eq=param.index('=')
params[param[:eq]]=float(param[eq+1:])
newfield.setcenter(params['x'],params['y'])
newfield.setfalloff(params['falloff'])
self.addfield(name,newfield)
newfield.name=name # fields have names?
except ValueError:
print "error on line: %s" % line
def savetofile(self,f):
for name,field in self.fields.items():
print >>f,"%s: x=%s y=%s falloff=%s" % (name,
field.center.x,field.center.y,
field.falloff)
def addfield(self,name,f):
"""consider the given field in this set with the given name"""
assert isinstance(f,Field)
self.fields[name]=f
def report(self,x,y):
"""reports active fields and their intensities"""
for name,f in self.fields.items():
intens=f.calc(x,y)
if intens>0:
print name,intens,
print
def getbounds(self):
"""returns xmin,xmax,ymin,ymax for the non-zero areas of this field"""
r=None
for f in self.fields.values():
rad=f.getdistforintensity(0)
fx,fy=f.center.x,f.center.y
fieldrect=Rect(fx-rad,fy-rad,rad*2,rad*2)
if r is None:
r=fieldrect
else:
r=r.union(fieldrect)
return r.left,r.right,r.top,r.bottom
class FieldDisplay:
"""the view for a Field."""
def __init__(self,canvas,field):
self.canvas=canvas
self.field=field
self.tags=[str(id(self))] # canvas tag to id our objects
def draw(self):
c=self.canvas
f=self.field
c.delete(self.tags)
w2c=self.canvas.world2canvas
def oval(rad,color):
p1=w2c(*(f.center-Pair(rad,rad)))
p2=w2c(*(f.center+Pair(rad,rad)))
c.create_oval(p1[0],p1[1],p2[0],p2[1],
outline=color,width=2,tags=self.tags,
outlinestipple='gray50')
oval(.01,'white')
for intens,color in ((1,'white'),
(.8,'gray90'),(.6,'gray80'),(.4,'gray60'),(.2,'gray50'),
(0,'#000080')):
oval(f.getdistforintensity(intens),color)
if hasattr(f,'name'):
p1=w2c(*f.center)
c.create_text(p1[0],p1[1],text=f.name,
fill='white',anchor='c')
class Tracker(tk.Frame):
"""whole tracker widget, which is mostly a view for a
FieldSet. tracker makes its own fieldset"""
# world coords of the visible canvas (preserved even in window resizes)
xmin=0
xmax=100
ymin=0
ymax=100
def __init__(self,master):
tk.Frame.__init__(self,master)
self.fieldset=FieldSet()
self.displays={} # Field : FieldDisplay
c=Zooming(self,bg='black')
c.pack(fill='both',exp=1)
for x,y in ((5,5),(5,95),(95,5),(95,95)):
c.create_text(x,y,text="%s,%s"%(x,y),fill='white')
c.bind("<Configure>",self.configcoords)
self.canvas=c
c.bind("<Motion>",
lambda ev: self.fieldset.report(*c.canvas2world(ev.x,ev.y)))
def configcoords(self,*args):
# force canvas coords to line up right
c=self.canvas
cornerx,cornery=c.canvas2world(0,0)
c.move(cornerx-self.xmin,
cornery-self.ymin)
c.setscale(0,0,
c.winfo_width()/(self.xmax-self.xmin),
c.winfo_height()/(self.ymax-self.ymin))
def autobounds(self):
"""figure out our bounds from the fieldset, and adjust the display zooms"""
self.xmin,self.xmax,self.ymin,self.ymax=self.fieldset.getbounds()
def addfield(self,name,f):
"""add the named Field to this display"""
self.fieldset.addfield(name,f)
self.displays[f]=FieldDisplay(self.canvas,f)
self.displays[f].draw()
root=tk.Tk()
tra=Tracker(root)
tra.pack(fill='both',exp=1)
tra.fieldset.loadfromfile(file("fieldsets/demo"))
for f in tra.fieldset.fields.values():
tra.displays[f]=FieldDisplay(tra.canvas,f)
tra.displays[f].draw()
tra.autobounds()
root.mainloop()
|