0
|
1 from Tix import *
|
|
2 from time import time # time is on my side
|
|
3 from util import subsetdict
|
|
4 from FlyingFader import FlyingFader
|
|
5 from uihelpers import get_selection
|
|
6
|
|
7 # statuses are:
|
|
8 # stopped - no cue is loaded or cue is stopped
|
|
9 # running - cue is running, not complete
|
|
10 # finished - cue is finished, next is loaded
|
|
11
|
|
12 stdfont = ('Arial', 10)
|
|
13
|
|
14 class Fader(Frame):
|
|
15 'User interface for cue fader'
|
|
16 def __init__(self, master, cues, scalelevels):
|
|
17 self.master = master
|
|
18 self.cues = cues
|
|
19 self.scalelevels = scalelevels
|
|
20 self.time_start = 0
|
|
21 self.init_layout()
|
|
22 self.stop()
|
|
23 def init_layout(self):
|
|
24 Frame.__init__(self, self.master)
|
|
25
|
|
26 # info variables
|
|
27 self.cuename = StringVar()
|
|
28 self.cuelength = DoubleVar()
|
|
29 self.cuetarget = StringVar()
|
|
30
|
|
31 # info about a running cue
|
|
32 self.cuestatus = StringVar() # text description
|
|
33 self.cuestatus.set("stopped")
|
|
34
|
|
35 self.cuepercent = DoubleVar() # percent complete
|
|
36 self.cuepercent.set(0)
|
|
37 self.cuepercent.trace('w', self.update_percent)
|
|
38 self.cuetimeelapse = StringVar() # time elapsed
|
|
39 self.cuetimeelapse.set('0s')
|
|
40 self.cuetimeleft = StringVar() # time left
|
|
41 self.cuetimeleft.set('0s')
|
|
42
|
|
43 buttonframe = Frame(self)
|
|
44 topframe = Frame(self) # to contain cue list and infoframe
|
|
45 infoframe = Frame(topframe)
|
|
46 topframe.pack()
|
|
47
|
|
48 self.listbox = ScrolledListBox(topframe,
|
|
49 command=self.update_selection)
|
|
50 self.listbox.listbox.configure({'exportselection' : 0,
|
|
51 'selectmode' : EXTENDED})
|
|
52 for c in self.cues:
|
|
53 self.listbox.listbox.insert(END, c.name)
|
|
54 self.listbox.pack(side=LEFT)
|
|
55 self.listbox.listbox.bind("<<ListboxSelect>>", self.update_selection,
|
|
56 add=1)
|
|
57 Button(buttonframe, text="Go", command=self.go, font=stdfont,
|
|
58 bg='green').pack(side=LEFT)
|
|
59 Button(buttonframe, text="Stop", command=self.stop, font=stdfont,
|
|
60 bg='red').pack(side=LEFT)
|
|
61 Button(buttonframe, text="Prev", command=self.prev,
|
|
62 font=stdfont).pack(side=LEFT)
|
|
63 nextbutton = Button(buttonframe, text="Next", command=self.next,
|
|
64 font=stdfont)
|
|
65 # Button(buttonframe, text="Load", command=self.mark_start, bg='grey80',
|
|
66 # font=stdfont).pack(side=LEFT)
|
|
67
|
|
68 Label(infoframe, textvariable=self.cuename,
|
|
69 font=('Arial', 12), bg='lightBlue').grid(columnspan=4, sticky=NE+SW)
|
|
70
|
|
71 Label(infoframe, text="Length", font=stdfont,
|
|
72 bg='lightPink').grid(row=1, sticky=NE+SW)
|
|
73 Label(infoframe, textvariable=self.cuelength,
|
|
74 font=stdfont).grid(row=1, column=1, columnspan=3, sticky=NE+SW)
|
|
75
|
|
76 Label(infoframe, text="Target", font=stdfont,
|
|
77 bg='lightPink').grid(row=2, sticky=NE+SW)
|
|
78 Label(infoframe, textvariable=self.cuetarget,
|
|
79 font=stdfont, wraplength=250).grid(row=2, column=1, columnspan=3,
|
|
80 sticky=NE+SW)
|
|
81
|
|
82 Label(infoframe, text="Status", font=stdfont,
|
|
83 bg='lightPink').grid(row=3, sticky=NE+SW)
|
|
84 Label(infoframe, textvariable=self.cuestatus,
|
|
85 font=stdfont).grid(row=3, column=1, columnspan=3, sticky=NE+SW)
|
|
86
|
|
87 Label(infoframe, text="Time Elapsed", font=stdfont,
|
|
88 bg='lightPink').grid(row=4, sticky=NE+SW)
|
|
89 Label(infoframe, textvariable=self.cuetimeelapse,
|
|
90 font=stdfont).grid(row=4, column=1, sticky=NE+SW)
|
|
91
|
|
92 Label(infoframe, text="Time Remain", font=stdfont,
|
|
93 bg='lightPink').grid(row=4, column=2, sticky=NE+SW)
|
|
94 Label(infoframe, textvariable=self.cuetimeleft,
|
|
95 font=stdfont).grid(row=4, column=3, sticky=NE+SW)
|
|
96
|
|
97 Label(infoframe, text="Percent Complete", font=stdfont,
|
|
98 bg='lightPink').grid(row=5, column=0, sticky=NE+SW)
|
|
99 self.percentlabel = Label(infoframe,
|
|
100 font=stdfont)
|
|
101 self.percentlabel.grid(row=5, column=1, columnspan=3, sticky=NE+SW)
|
|
102
|
|
103 # s = Scale(infoframe, variable=self.cuepercent,
|
|
104 s = Scale(buttonframe, variable=self.cuepercent,
|
|
105 showvalue=0, length=220,
|
|
106 width=18, sliderlength=30,
|
|
107 to=100,res=.1,from_=0,bd=1, font=stdfont,
|
|
108 orient='horiz')
|
|
109 # s.grid(row=6, columnspan=4, sticky='ew')
|
|
110 nextbutton.pack(side=RIGHT)
|
|
111 s.pack(side=RIGHT, expand=1, fill=X)
|
|
112
|
|
113 infoframe.pack(side=RIGHT, fill=BOTH, expand=1)
|
|
114 buttonframe.pack(side=BOTTOM, expand=1, fill=X)
|
|
115
|
|
116 self.listbox.listbox.select_set(0)
|
|
117 self.update_selection()
|
|
118 def mark_start(self):
|
|
119 self.time_start = time()
|
|
120 startlevels = dict([(k, v.get()) for k, v in self.scalelevels.items()])
|
|
121 # print "going to mark with", startlevels
|
|
122 self.current.start(startlevels, self.time_start)
|
|
123 def update_percent(self, *args):
|
|
124 if self.cuestatus.get() != 'running':
|
|
125 self.cuestatus.set("running")
|
|
126 self.mark_start()
|
|
127
|
|
128 percent = self.cuepercent.get()
|
|
129 self.percentlabel.config(text='%.1f%%' % percent)
|
|
130 percent /= 100
|
|
131
|
|
132 elapsed = percent * self.current.dur
|
|
133 self.cuetimeelapse.set('%.1fs' % elapsed)
|
|
134 self.cuetimeleft.set('%.1fs' % (self.current.dur - elapsed))
|
|
135
|
|
136 newlevels = self.current.get_levels(self.time_start + elapsed)
|
|
137 # print "newlevels", newlevels
|
|
138 for ch, lev in newlevels.items():
|
|
139 try:
|
|
140 self.scalelevels[ch].set(lev)
|
|
141 except KeyError:
|
|
142 pass
|
|
143
|
|
144 def update_selection(self, *args):
|
|
145 self.cuestatus.set('stopped')
|
|
146 selection = get_selection(self.listbox.listbox)
|
|
147 self.current = self.cues[selection]
|
|
148 self.cuename.set(self.current.name)
|
|
149 self.cuelength.set(self.current.dur)
|
|
150 target = ', '.join(['%s -> %.2f' % (n, lev)
|
|
151 for n, lev in self.current.get_end_levels().items()])
|
|
152 self.cuetarget.set(target)
|
|
153 self.cuetimeelapse.set('0s')
|
|
154 self.cuetimeleft.set('%.1fs' % self.current.dur)
|
|
155 self.cuepercent.set(0)
|
|
156 def go(self):
|
|
157 self.update_selection()
|
|
158 self.cuestatus.set("running")
|
|
159 self.mark_start()
|
|
160 self.running_loop()
|
|
161 def stop(self):
|
|
162 self.cuestatus.set('stopped')
|
|
163 def prev(self):
|
|
164 self.stop()
|
|
165 selection = get_selection(self.listbox.listbox)
|
|
166 if selection != 0:
|
|
167 self.listbox.listbox.select_clear(selection)
|
|
168 self.listbox.listbox.select_set(selection - 1)
|
|
169 self.update_selection()
|
|
170 self.mark_start()
|
|
171 def next(self):
|
|
172 self.stop()
|
|
173 selection = get_selection(self.listbox.listbox)
|
|
174 if selection != self.listbox.listbox.size() - 1:
|
|
175 self.listbox.listbox.select_clear(selection)
|
|
176 self.listbox.listbox.select_set(selection + 1)
|
|
177 self.update_selection()
|
|
178 self.mark_start()
|
|
179 def running_loop(self):
|
|
180 if self.cuestatus.get() == 'stopped':
|
|
181 return
|
|
182 curtime = time()
|
|
183 elapsed = (curtime - self.time_start)
|
|
184
|
|
185 if elapsed > self.current.dur:
|
|
186 self.cuestatus.set('stopped')
|
|
187 self.cuepercent.set(100)
|
|
188
|
|
189 # advance cues if okay
|
|
190 self.next()
|
|
191 return
|
|
192
|
|
193 self.cuepercent.set(100 * elapsed / self.current.dur)
|
|
194 self.after(30, self.running_loop)
|