Mercurial > code > home > repos > light9
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) |