0
|
1 from Patch import *
|
|
2 from time import time
|
|
3 from Tix import *
|
|
4 from types import TupleType
|
|
5
|
|
6 stdfont = ('Arial', 8)
|
|
7
|
|
8 class Param: # abstract
|
|
9 def get_value(self):
|
|
10 pass
|
|
11 def set_value(self, v):
|
|
12 pass
|
|
13 def draw_tk(self, frame):
|
|
14 pass
|
|
15 def __getstate__(self):
|
|
16 return {'value' : self.get_value()}
|
|
17 def __setstate__(self, dict):
|
|
18 self.value = StringVar()
|
|
19 self.set_value(dict['value'])
|
|
20
|
|
21 class CheckboxParam(Param):
|
|
22 def __init__(self, initial=0):
|
|
23 self.value = IntVar()
|
|
24 self.value.set(initial)
|
|
25 def get_value(self):
|
|
26 return self.value.get()
|
|
27 def draw_tk(self, frame):
|
|
28 self.c = Checkbutton(frame, variable=self.value)
|
|
29 self.c.pack()
|
|
30
|
|
31 class SliderParam(Param):
|
|
32 def __init__(self, range=(0, 1), res=0.01, initial=0, orient='v',
|
|
33 **options):
|
|
34 self.value = DoubleVar()
|
|
35 self.value.set(initial)
|
|
36 self.options = {'res' : res, 'to' : range[0], 'from' : range[1],
|
|
37 'orient' : orient,
|
|
38 'font' : stdfont, 'length' : 50, 'sliderlength' : 10,
|
|
39 'width' : 10}
|
|
40 self.options.update(options)
|
|
41 def get_value(self):
|
|
42 return self.value.get()
|
|
43 def draw_tk(self, frame):
|
|
44 s = Scale(frame, variable=self.value, **self.options)
|
|
45 s.pack()
|
|
46
|
|
47 class TextParam(Param):
|
|
48 def __init__(self, initial=''):
|
|
49 self.value = StringVar()
|
|
50 self.value.set(initial)
|
|
51 def get_value(self):
|
|
52 return self.value.get()
|
|
53 def select_all(self, evt):
|
|
54 self.e.select_range(0, END)
|
|
55 def unfocus(self, evt):
|
|
56 self.frame.focus()
|
|
57 def draw_tk(self, frame):
|
|
58 self.frame = frame
|
|
59 self.e = Entry(frame, textvariable=self.value)
|
|
60 self.e.bind("<Return>", self.unfocus)
|
|
61 self.e.pack()
|
|
62
|
|
63 class ListParam(Param):
|
|
64 def __init__(self, options=(), multiple=0, initial=''):
|
|
65 self.value = StringVar()
|
|
66 self.value.set(initial)
|
|
67 self.options = options
|
|
68 if multiple:
|
|
69 self.selectmode = 'MULTIPLE'
|
|
70 else:
|
|
71 self.selectmode = 'SINGLE'
|
|
72 def get_value(self):
|
|
73 try:
|
|
74 return self.l.get(self.l.curselection())
|
|
75 except:
|
|
76 return ''
|
|
77 def draw_tk(self, frame):
|
|
78 self.l = Listbox(frame, selectmode=self.selectmode, font=stdfont,
|
|
79 width=max([len(o) for o in self.options]),
|
|
80 height=len(self.options), exportselection=0)
|
|
81 for o in self.options:
|
|
82 self.l.insert(END, o)
|
|
83 self.l.pack()
|
|
84
|
|
85 class LabelParam(Param):
|
|
86 def __init__(self, initial=''):
|
|
87 self.value = StringVar()
|
|
88 self.value.set(initial)
|
|
89 def get_value(self):
|
|
90 return self.value.get()
|
|
91 def set_value(self, v):
|
|
92 if 'value' not in self.__dict__:
|
|
93 self.value = StringVar()
|
|
94 self.value.set(v)
|
|
95 def draw_tk(self, frame):
|
|
96 l = Label(frame, textvariable=self.value, font=stdfont)
|
|
97 l.pack()
|
|
98
|
|
99 class ButtonParam(Param):
|
|
100 def __init__(self, text, **options):
|
|
101 self.options = {'text' : text}
|
|
102 self.options.update(options)
|
|
103 self.pressed = 0
|
|
104 self.unread = 0 # unread button presses
|
|
105 def draw_tk(self, frame):
|
|
106 b = Button(frame, **self.options)
|
|
107 b.pack()
|
|
108 b.bind('<ButtonPress>', self.activate)
|
|
109 b.bind('<ButtonRelease>', self.deactivate)
|
|
110 def get_value(self):
|
|
111 if self.unread:
|
|
112 self.unread = 0
|
|
113 return 1
|
|
114
|
|
115 return self.pressed
|
|
116 def activate(self, evt):
|
|
117 self.pressed = 1
|
|
118 self.unread = 1
|
|
119 def deactivate(self, evt):
|
|
120 self.pressed = 0
|
|
121
|
|
122 class Params:
|
|
123 def __init__(self):
|
|
124 self.params = {}
|
|
125 def add_param(self, name, param):
|
|
126 self.params[name] = param
|
|
127 def get_param_value(self, name):
|
|
128 return self.params[name].get_value()
|
|
129 def __getitem__(self, name):
|
|
130 return self.params[name].get_value()
|
|
131 def __setitem__(self, name, value):
|
|
132 self.params[name].set_value(value)
|
|
133 def draw_tk(self, frame):
|
|
134 for name,param in self.params.items():
|
|
135 f = Frame(frame)
|
|
136 l = Label(f, text=name, font=stdfont)
|
|
137 l.pack(side='left')
|
|
138 pframe = Frame(f)
|
|
139 param.draw_tk(pframe)
|
|
140 pframe.pack(side='right')
|
|
141 f.pack()
|
|
142
|
|
143 class SliderAdjuster:
|
|
144 def __init__(self):
|
|
145 self.var = None
|
|
146 self.atzero = 0
|
|
147 def set(self, level):
|
|
148 if self.var is not None:
|
|
149 self.var.set(level)
|
|
150 def get(self, level):
|
|
151 if self.var is not None:
|
|
152 return self.var.get()
|
|
153 return None
|
|
154 def justturnedon(self):
|
|
155 return self.atzero
|
|
156 def __getstate__(self):
|
|
157 state = self.__dict__.copy()
|
|
158 # remove var (non-pickleable)
|
|
159 try:
|
|
160 del state['var']
|
|
161 except KeyError:
|
|
162 pass
|
|
163 return state
|
|
164 # no setstate needed
|
|
165
|
|
166 class Sub:
|
|
167 def __init__(self, name, levels, dimmers=68, color=None):
|
|
168 self.name = name # keep this consistent please
|
|
169 self.levels = levels
|
|
170 self.dimmers = dimmers # needed?
|
|
171 self.is_effect = callable(self.levels)
|
|
172 self.slideradjuster = SliderAdjuster()
|
|
173 self.namecache = {}
|
|
174 if self.is_effect:
|
|
175 self.params = Params()
|
|
176 self.generator = self.levels(self.params, self.slideradjuster)
|
|
177 self.generator.next()
|
|
178 self.color = color
|
|
179 def resolve_name(self, ch_name):
|
|
180 if ch_name in self.namecache:
|
|
181 return self.namecache[ch_name]
|
|
182 else:
|
|
183 resolved = get_dmx_channel(ch_name)
|
|
184 self.namecache[ch_name] = resolved
|
|
185 return resolved
|
|
186 def set_slider_var(self, slidervar):
|
|
187 if self.is_effect:
|
|
188 self.slideradjuster.var = slidervar
|
|
189 def draw_tk(self, frame):
|
|
190 if self.is_effect:
|
|
191 self.params.draw_tk(frame)
|
|
192 def get_state(self):
|
|
193 state = self.__dict__.copy()
|
|
194 if self.is_effect:
|
|
195 del state['levels']
|
|
196 del state['generator']
|
|
197
|
|
198 return state
|
|
199 def set_state(self, statedict):
|
|
200 self.__dict__.update(statedict)
|
|
201 def get_levels(self, level):
|
|
202 """returns a scaled version of the levels in the sub; channel names
|
|
203 are resolved to numbers"""
|
|
204 d = {}
|
|
205 if level == 0:
|
|
206 self.slideradjuster.atzero = 1
|
|
207 return d
|
|
208 if self.is_effect: # effect
|
|
209 d = self.generator.next()
|
|
210 self.slideradjuster.atzero = 0
|
|
211 return dict([(get_dmx_channel(ch), float(lev) * float(level))
|
|
212 for ch, lev in d.items()])
|
|
213 else: # dictionary (standard)
|
|
214 d = self.levels
|
|
215 return dict([(self.resolve_name(ch), float(lev) * float(level))
|
|
216 for ch, lev in d.items()])
|
|
217
|
|
218 #
|
|
219 # methods for Subediting to use
|
|
220 #
|
|
221 def getlevels(self):
|
|
222 return self.levels.copy()
|
|
223 def reviselevels(self,levels):
|
|
224 # we can accept these new levels; subediting has done all the work
|
|
225 self.levels.update(levels)
|
|
226
|
|
227
|
|
228
|
|
229 def reload_data(dummy):
|
|
230 global subs, cues
|
|
231 if dummy:
|
|
232 import ConfigDummy as Config
|
|
233 else:
|
|
234 import Config
|
|
235
|
|
236 reload(Config)
|
|
237
|
|
238 subs = {}
|
|
239 for name, levels in Config.subs.items():
|
|
240 if type(name) == TupleType:
|
|
241 name, color = name
|
|
242 else:
|
|
243 color = None
|
|
244
|
|
245 subs[name] = Sub(name, levels, color=color)
|
|
246
|
|
247 # subs = dict([(name, Sub(levels)) for name, levels in Config.subs.items()])
|
|
248
|
|
249 cues = Config.cues
|
|
250
|
|
251 def longestsubname():
|
|
252 return max([len(x) for x in subs.keys()])
|