comparison bin/subcomposer @ 803:ce4fffe8e413

update SC to read rdf graph Ignore-this: 7f6788bae887723c9ac12644c1a382da
author drewp@bigasterisk.com
date Wed, 18 Jul 2012 09:59:10 +0000
parents 5442f5d8979a
children 317c2d2e22da
comparison
equal deleted inserted replaced
802:5442f5d8979a 803:ce4fffe8e413
3 from __future__ import division, nested_scopes 3 from __future__ import division, nested_scopes
4 import sys,os,time,atexit 4 import sys,os,time,atexit
5 from optparse import OptionParser 5 from optparse import OptionParser
6 import Tkinter as tk 6 import Tkinter as tk
7 import louie as dispatcher 7 import louie as dispatcher
8 from twisted.internet import reactor, tksupport, task
8 9
9 import run_local 10 import run_local
10 from light9.dmxchanedit import Levelbox 11 from light9.dmxchanedit import Levelbox
11 from light9 import dmxclient, Patch, Submaster, showconfig 12 from light9 import dmxclient, Patch, Submaster, showconfig, prof
12 from light9.uihelpers import toplevelat 13 from light9.uihelpers import toplevelat
14 from light9.rdfdb.syncedgraph import SyncedGraph
13 15
14 class Subcomposer(tk.Frame): 16 class Subcomposer(tk.Frame):
15 def __init__(self, master, levelboxopts=None, dmxdummy=0, numchannels=72, 17 def __init__(self, master, graph):
16 use_persistentlevels=0):
17 tk.Frame.__init__(self, master, bg='black') 18 tk.Frame.__init__(self, master, bg='black')
18 self.dmxdummy = dmxdummy 19 self.graph = graph
19 self.numchannels = numchannels
20 20
21 self.levels = [0]*numchannels # levels should never get overwritten, just edited 21 self.levelbox = Levelbox(self, graph)
22
23 self.levelbox = Levelbox(self, num_channels=numchannels)
24 self.levelbox.pack(side='top') 22 self.levelbox.pack(side='top')
25 # the dmx levels we edit and output, range is 0..1 (dmx chan 1 is
26 # the 0 element)
27 self.levelbox.setlevels(self.levels)
28 23
29 self.savebox = EntryCommand(self, cmd=self.savenewsub) 24 self.savebox = EntryCommand(self, cmd=self.savenewsub)
30 self.savebox.pack(side='top') 25 self.savebox.pack(side='top')
31 26
32 self.loadbox = EntryCommand(self, verb="Load", cmd=self.loadsub) 27 self.loadbox = EntryCommand(self, verb="Load", cmd=self.loadsub)
33 self.loadbox.pack(side='top') 28 self.loadbox.pack(side='top')
34 29
35 def alltozero(): 30 def alltozero():
36 self.set_levels([0] * self.numchannels) 31 for lev in self.levelbox.levels:
37 dispatcher.send("levelchanged") 32 lev.setlevel(0)
38 33
39 tk.Button(self, text="all to zero", command=alltozero).pack(side='top') 34 tk.Button(self, text="all to zero", command=alltozero).pack(side='top')
40 35
41 dispatcher.connect(self.levelchanged,"levelchanged") 36 dispatcher.connect(self.sendupdate, "levelchanged")
42 dispatcher.connect(self.sendupdate,"levelchanged")
43
44 if use_persistentlevels:
45 self.persistentlevels()
46
47 self.lastupdate=0 # time we last sent to dmx
48
49 self.lastsent=[] # copy of levels
50 37
51 def fill_both_boxes(self, subname): 38 def fill_both_boxes(self, subname):
52 for box in [self.savebox, self.loadbox]: 39 for box in [self.savebox, self.loadbox]:
53 box.set(subname) 40 box.set(subname)
54
55 def persistentlevels(self):
56 """adjusts levels from subcomposer.savedlevels, if possible; and
57 arranges to save the levels in that file upon exit"""
58 self.load_levels()
59 atexit.register(self.save_levels)
60 41
61 def save_levels(self, *args): 42 def save_levels(self, *args):
62 levelfile = file("subcomposer.savedlevels","w") 43 levelfile = file("subcomposer.savedlevels","w")
63 levelfile.write(" ".join(map(str, self.levels))) 44 levelfile.write(" ".join(map(str, self.levels)))
64 45
67 levelfile = file("subcomposer.savedlevels","r") 48 levelfile = file("subcomposer.savedlevels","r")
68 levels = map(float, levelfile.read().split()) 49 levels = map(float, levelfile.read().split())
69 self.set_levels(levels) 50 self.set_levels(levels)
70 except IOError: 51 except IOError:
71 pass 52 pass
72
73 def levelchanged(self, channel=None, newlevel=None):
74 if channel is not None and newlevel is not None:
75 if channel>len(self.levels):
76 return
77 self.levels[channel-1]=max(0,min(1,float(newlevel)))
78 self.levelbox.setlevels(self.levels)
79 53
80 def savenewsub(self, subname): 54 def savenewsub(self, subname):
81 leveldict={} 55 leveldict={}
82 for i,lev in zip(range(len(self.levels)),self.levels): 56 for i,lev in zip(range(len(self.levels)),self.levels):
83 if lev!=0: 57 if lev!=0:
90 """puts a sub into the levels, replacing old level values""" 64 """puts a sub into the levels, replacing old level values"""
91 s=Submaster.Submasters(showconfig.getGraph()).get_sub_by_name(subname) 65 s=Submaster.Submasters(showconfig.getGraph()).get_sub_by_name(subname)
92 self.set_levels(s.get_dmx_list()) 66 self.set_levels(s.get_dmx_list())
93 dispatcher.send("levelchanged") 67 dispatcher.send("levelchanged")
94 68
69 def toDmxLevels(self):
70 # the dmx levels we edit and output, range is 0..1 (dmx chan 1 is
71 # the 0 element)
72 out = {}
73 for lev in self.levelbox.levels:
74 out[lev.channelnum] = lev.currentlevel
75 if not out:
76 return []
77
78 return [out.get(i, 0) for i in range(max(out.keys()) + 1)]
79
95 def sendupdate(self): 80 def sendupdate(self):
96 if not self.dmxdummy: 81 dmxclient.outputlevels(self.toDmxLevels(), twisted=True)
97 dmxclient.outputlevels(self.levels)
98 self.lastupdate = time.time()
99 self.lastsent = self.levels[:]
100 82
101 def considersendupdate(self, use_after_loop=0):
102 """If use_after_loop is true, it is the period of the after loop."""
103 if self.lastsent != self.levels or time.time() > self.lastupdate + 1:
104 self.sendupdate()
105 if use_after_loop:
106 self.after(use_after_loop, self.considersendupdate, use_after_loop)
107
108 def set_levels(self, levels):
109 oldLen = len(self.levels)
110 self.levels[:] = levels + [0] * (oldLen - len(levels))
111 dispatcher.send("levelchanged")
112 83
113 class EntryCommand(tk.Frame): 84 class EntryCommand(tk.Frame):
114 def __init__(self, master, verb="Save", cmd=None): 85 def __init__(self, master, verb="Save", cmd=None):
115 tk.Frame.__init__(self, master, bd=2, relief='raised') 86 tk.Frame.__init__(self, master, bd=2, relief='raised')
116 tk.Label(self, text="Sub name:").pack(side='left') 87 tk.Label(self, text="Sub name:").pack(side='left')
129 def set(self, text): 100 def set(self, text):
130 self.entry.delete(0, 'end') 101 self.entry.delete(0, 'end')
131 self.entry.insert(0, text) 102 self.entry.insert(0, text)
132 103
133 104
134 def open_sub_editing_window(subname, use_mainloop=1, dmxdummy=0):
135 if use_mainloop:
136 toplevel = tk.Tk()
137 else:
138 toplevel = tk.Toplevel()
139 if dmxdummy:
140 dummy_str = ' (dummy)'
141 else:
142 dummy_str = ''
143 toplevel.title("Subcomposer: %s%s" % (subname, dummy_str))
144 sc = Subcomposer(toplevel, use_persistentlevels=0, dmxdummy=dmxdummy)
145 sc.pack(fill='both', expand=1)
146 sc.loadsub(subname)
147 sc.considersendupdate(use_after_loop=10)
148 if use_mainloop:
149 tk.mainloop()
150
151 ############################# 105 #############################
152 106
153 if __name__ == "__main__": 107 if __name__ == "__main__":
154 parser = OptionParser(usage="%prog [subname]") 108 parser = OptionParser(usage="%prog [subname]")
155 parser.add_option('--no-geometry', action='store_true', 109 parser.add_option('--no-geometry', action='store_true',
160 root.config(bg='black') 114 root.config(bg='black')
161 root.tk_setPalette("#004633") 115 root.tk_setPalette("#004633")
162 if not opts.no_geometry: 116 if not opts.no_geometry:
163 toplevelat("subcomposer", root) 117 toplevelat("subcomposer", root)
164 118
165 sc = Subcomposer(root, dmxdummy=0, 119 graph = SyncedGraph("subcomposer")
166 #numchannels=276 # use this to see all the skyline dims 120
167 #numchannels=118 121 sc = Subcomposer(root, graph)
168 )
169 sc.pack() 122 sc.pack()
170 123
171 tk.Label(root,text="Bindings: B1 adjust level; B2 set full; B3 instant bump", 124 tk.Label(root,text="Bindings: B1 adjust level; B2 set full; B3 instant bump",
172 font="Helvetica -12 italic",anchor='w').pack(side='top',fill='x') 125 font="Helvetica -12 italic",anchor='w').pack(side='top',fill='x')
173 126
174 if len(args) == 1: 127 if len(args) == 1:
175 root.config(bg='green') # trying to make these look distinctive 128 root.config(bg='green') # trying to make these look distinctive
176 sc.loadsub(args[0]) 129 sc.loadsub(args[0])
177 sc.fill_both_boxes(args[0]) 130 sc.fill_both_boxes(args[0])
178 131
179 while 1: 132 task.LoopingCall(sc.sendupdate).start(1)
180 try:
181 root.update()
182 except tk.TclError:
183 break
184 133
185 sc.considersendupdate() 134 tksupport.install(root,ms=10)
186 time.sleep(.01) 135 prof.run(reactor.run, profile=False)