Mercurial > code > home > repos > light9
annotate light8/Lightboard.py @ 2405:69ca2b2fc133
overcomplicated attempt at persisting the pane layout in the rdf graph
this was hard because we have to somehow wait for the graph to load before config'ing the panes
author | drewp@bigasterisk.com |
---|---|
date | Fri, 17 May 2024 16:58:26 -0700 |
parents | 35e0c467a292 |
children |
rev | line source |
---|---|
112
afbdae5e1359
dmx light output is now via a separate process which light8 talks to.
drewp
parents:
107
diff
changeset
|
1 from __future__ import nested_scopes,division |
0 | 2 |
3 from Tix import * | |
4 from signal import signal, SIGINT | |
103
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
5 from time import time |
78
0969d8a6729d
support for external sliders. fill in ExternalInput with real IO
dmcc
parents:
74
diff
changeset
|
6 import sys, cPickle, random |
0 | 7 |
8 from uihelpers import * | |
9 from panels import * | |
10 from Xfader import * | |
11 from subediting import Subediting | |
12 from Fader import Fader | |
79 | 13 from ExternalInput import ExternalSliders |
14 import io, stage, Subs, Patch, ExtSliderMapper | |
119 | 15 import dmxclient |
0 | 16 |
17 class Pickles: | |
67 | 18 def __init__(self, scalelevels, subs=None, windowpos=None): |
0 | 19 self.scalelevels = dict([(name, lev.get()) |
20 for name, lev in scalelevels.items()]) | |
21 self.substate = dict([(name, subobj.get_state()) | |
22 for name, subobj in subs]) | |
67 | 23 self.windowpos = windowpos |
0 | 24 |
25 class Lightboard: | |
112
afbdae5e1359
dmx light output is now via a separate process which light8 talks to.
drewp
parents:
107
diff
changeset
|
26 def __init__(self, master, DUMMY): |
0 | 27 self.master = master |
112
afbdae5e1359
dmx light output is now via a separate process which light8 talks to.
drewp
parents:
107
diff
changeset
|
28 |
0 | 29 self.DUMMY = DUMMY |
74 | 30 self.jostle_mode = 0 |
104
15ead14b4dd1
result of 7.13 performance, some ExtSliderMapper fixes
dmcc
parents:
103
diff
changeset
|
31 self.lastline = None |
0 | 32 |
107 | 33 self.channel_levels = [] # these are actually the labels for the |
34 # channel levels, and should probably be moved | |
35 # to panels.Leveldisplay | |
0 | 36 self.scalelevels = {} |
107 | 37 |
38 self.lastsublevels = {} # to determine which subs changed | |
39 self.unchangedeffect = {} # dict of levels for lights that didn't | |
40 # change last time | |
41 self.lastunchangedgroup = {} | |
42 | |
78
0969d8a6729d
support for external sliders. fill in ExternalInput with real IO
dmcc
parents:
74
diff
changeset
|
43 # doesn't draw any UI yet-- look for self.xfader.setupwidget() |
0969d8a6729d
support for external sliders. fill in ExternalInput with real IO
dmcc
parents:
74
diff
changeset
|
44 self.xfader = Xfader(self.scalelevels) |
0 | 45 self.oldlevels = [None] * 68 # never replace this; just clear it |
46 self.subediting = Subediting(currentoutputlevels=self.oldlevels) | |
47 | |
68 | 48 self.windowpos = 0 |
0 | 49 self.get_data() |
50 self.buildinterface() | |
51 self.load() | |
112
afbdae5e1359
dmx light output is now via a separate process which light8 talks to.
drewp
parents:
107
diff
changeset
|
52 |
afbdae5e1359
dmx light output is now via a separate process which light8 talks to.
drewp
parents:
107
diff
changeset
|
53 print "Light 8.8: Entering backgroundloop" |
0 | 54 self.backgroundloop() |
62
2f2eb802e93d
stage shows levels now. aims have blue halo for easy recognition.
dmcc
parents:
61
diff
changeset
|
55 self.updatestagelevels() |
103
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
56 self.rec_file = open('light9.log', 'a') |
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
57 self.record_start() |
0 | 58 |
59 def buildinterface(self): | |
102 | 60 print "Light 8.8: Constructing interface..." |
0 | 61 for w in self.master.winfo_children(): |
62 w.destroy() | |
63 | |
102 | 64 print "\tstage" |
78
0969d8a6729d
support for external sliders. fill in ExternalInput with real IO
dmcc
parents:
74
diff
changeset
|
65 stage_tl = toplevelat('stage') |
0 | 66 s = stage.Stage(stage_tl) |
67 stage.createlights(s) | |
68 s.setsubediting(self.subediting) | |
69 s.pack() | |
62
2f2eb802e93d
stage shows levels now. aims have blue halo for easy recognition.
dmcc
parents:
61
diff
changeset
|
70 self.stage = s # save it |
0 | 71 |
78
0969d8a6729d
support for external sliders. fill in ExternalInput with real IO
dmcc
parents:
74
diff
changeset
|
72 sub_tl = toplevelat('sub') |
0969d8a6729d
support for external sliders. fill in ExternalInput with real IO
dmcc
parents:
74
diff
changeset
|
73 scene_tl = toplevelat('scenes') |
0969d8a6729d
support for external sliders. fill in ExternalInput with real IO
dmcc
parents:
74
diff
changeset
|
74 effect_tl = toplevelat('effect') |
0969d8a6729d
support for external sliders. fill in ExternalInput with real IO
dmcc
parents:
74
diff
changeset
|
75 |
131 | 76 print "\tslider patching -- It can't be turned off!" |
78
0969d8a6729d
support for external sliders. fill in ExternalInput with real IO
dmcc
parents:
74
diff
changeset
|
77 mapping_tl = toplevelat('mapping') |
79 | 78 self.slidermapper = ExtSliderMapper.ExtSliderMapper(mapping_tl, |
79 self.scalelevels, | |
103
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
80 ExternalSliders(), |
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
81 self) |
78
0969d8a6729d
support for external sliders. fill in ExternalInput with real IO
dmcc
parents:
74
diff
changeset
|
82 self.slidermapper.pack() |
0 | 83 |
102 | 84 print "\tsubmaster control" |
107 | 85 self.subpanels = Subpanels(sub_tl, effect_tl, scene_tl, self, |
86 self.scalelevels, Subs, self.xfader, | |
87 self.changelevel, self.subediting, | |
88 Subs.longestsubname()) | |
89 | |
90 for n, lev in self.scalelevels.items(): | |
91 self.lastsublevels[n] = lev.get() | |
0 | 92 |
102 | 93 print "\tlevel display" |
78
0969d8a6729d
support for external sliders. fill in ExternalInput with real IO
dmcc
parents:
74
diff
changeset
|
94 leveldisplay_tl = toplevelat('leveldisplay') |
0 | 95 leveldisplay_tl.bind('<Escape>', sys.exit) |
96 | |
97 self.leveldisplay = Leveldisplay(leveldisplay_tl, self.channel_levels) | |
107 | 98 # I don't think we need this |
99 # for i in range(0,len(self.channel_levels)): | |
100 # self.channel_levels[i].config(text=self.oldlevels[i]) | |
101 # colorlabel(self.channel_levels[i]) | |
0 | 102 |
102 | 103 print "\tconsole" |
0 | 104 Console(self) |
105 | |
106 # root frame | |
102 | 107 print "\tcontrol panel" |
108 self.master.configure(bg='black') | |
74 | 109 controlpanel = Controlpanel(self.master, self.xfader, self.refresh, |
107 | 110 self.quit, self.toggle_jostle, self.nonzerosubs) |
0 | 111 |
102 | 112 print "\tcrossfader" |
0 | 113 xf=Frame(self.master) |
114 xf.pack(side='right') | |
115 | |
116 self.master.bind('<q>', self.quit) | |
117 self.master.bind('<r>', self.refresh) | |
118 leveldisplay_tl.bind('<q>', self.quit) | |
119 leveldisplay_tl.bind('<r>', self.refresh) | |
120 | |
121 self.xfader.setupwidget(xf) | |
122 controlpanel.pack() | |
123 | |
102 | 124 print "\tcue fader (skipped)" |
125 # cuefader_tl = toplevelat('cuefader') | |
126 # cuefader = Fader(cuefader_tl, Subs.cues, self.scalelevels) | |
127 # cuefader.pack() | |
128 print "Light 8.8: Everything's under control" | |
129 | |
0 | 130 |
131 def get_data(self,*args): | |
132 Subs.reload_data(self.DUMMY) | |
133 Patch.reload_data(self.DUMMY) | |
102 | 134 print "Light 8.8:", len(Patch.patch), "dimmers patched" |
135 print "Light 8.8:", len(Subs.subs), "submasters loaded" | |
0 | 136 |
137 def refresh(self, *args): | |
138 'rebuild interface, reload data' | |
103
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
139 print "Light 8.8: Refresh initiated. Cross your fingers." |
0 | 140 self.get_data() |
103
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
141 print "Light 8.8: Subediting refreshed" |
0 | 142 self.subediting.refresh() |
103
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
143 print "Light 8.8: Rebuilding interface..." |
0 | 144 self.buildinterface() |
145 bindkeys(self.master,'<Escape>', self.quit) | |
103
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
146 print "Light 8.8: Setting up slider patching..." |
101 | 147 self.slidermapper.setup() |
148 # self.master.tk_setPalette('gray40') | |
103
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
149 print "Light 8.8: Now back to your regularly scheduled Light 8" |
0 | 150 |
151 def stageassub(self): | |
152 """returns the current onstage lighting as a levels | |
153 dictionary, skipping the zeros, and using names where | |
154 possible""" | |
155 levs=self.oldlevels | |
156 | |
157 return dict([(Patch.get_channel_name(i),l) for i,l | |
158 in zip(range(1,len(levs)+1),levs) | |
159 if l>0]) | |
68 | 160 def save_sub(self, name, levels, refresh=1): |
0 | 161 if not name: |
162 print "Enter sub name in console." | |
163 return | |
164 | |
165 st = '' | |
166 linebuf = 'subs["%s"] = {' % name | |
167 for channame,lev in levels.items(): | |
168 if len(linebuf) > 60: | |
169 st += linebuf + '\n ' | |
170 linebuf = '' | |
171 | |
172 linebuf += ' "%s" : %d,' % (channame, lev) | |
173 st += linebuf + '}\n' | |
174 if self.DUMMY: | |
175 filename = 'ConfigDummy.py' | |
176 else: | |
177 filename = 'Config.py' | |
178 f = open(filename, 'a') | |
179 f.write(st) | |
180 f.close() | |
181 print 'Added sub:', st | |
68 | 182 if refresh: |
183 self.refresh() | |
0 | 184 |
185 # this is called on a loop, and ALSO by the Scales | |
186 def changelevel(self, *args): | |
187 'Amp trims slider' | |
188 | |
78
0969d8a6729d
support for external sliders. fill in ExternalInput with real IO
dmcc
parents:
74
diff
changeset
|
189 # load levels from external sliders |
0969d8a6729d
support for external sliders. fill in ExternalInput with real IO
dmcc
parents:
74
diff
changeset
|
190 extlevels = self.slidermapper.get_levels() |
0969d8a6729d
support for external sliders. fill in ExternalInput with real IO
dmcc
parents:
74
diff
changeset
|
191 for name, val in extlevels.items(): |
79 | 192 if name in self.scalelevels: |
95
d5deeed83228
FancyDoubleVar is a DoubleVar where you can temporarily disable the callbacks
drewp
parents:
79
diff
changeset
|
193 sl = self.scalelevels[name] |
d5deeed83228
FancyDoubleVar is a DoubleVar where you can temporarily disable the callbacks
drewp
parents:
79
diff
changeset
|
194 sl.set(val) |
107 | 195 |
196 # newstart = time() | |
197 | |
198 # learn what changed | |
199 unchangedgroup = {} | |
200 changedgroup = {} | |
201 for name, lastlevel in self.lastsublevels.items(): | |
202 newlevel = self.scalelevels[name].get() | |
203 if lastlevel != newlevel: | |
204 changedgroup[name] = newlevel | |
205 else: | |
206 unchangedgroup[name] = newlevel | |
207 | |
208 changedeffect = {} | |
209 if not changedgroup: | |
210 # should load levels from last time | |
211 pass | |
212 else: | |
213 # calculate effect of new group. this should take no time if | |
214 # nothing changed | |
215 for name, level in changedgroup.items(): | |
216 newlevels = Subs.subs[name].get_levels(level=level) | |
217 for (ch, fadelev) in newlevels.items(): | |
218 changedeffect[ch-1] = \ | |
219 max(changedeffect.get(ch-1, 0), fadelev) | |
220 | |
221 if unchangedgroup != self.lastunchangedgroup: | |
222 # unchanged group changed! (confusing, huh?) | |
223 # this means: the static subs from the last time are not the same | |
224 # as they are this time, so we recalculate effect of unchanged group | |
225 self.unchangedeffect = {} | |
226 for name, level in unchangedgroup.items(): | |
227 newlevels = Subs.subs[name].get_levels(level=level) | |
228 for (ch, fadelev) in newlevels.items(): | |
229 self.unchangedeffect[ch-1] = \ | |
230 max(self.unchangedeffect.get(ch-1, 0), fadelev) | |
231 self.lastunchangedgroup = unchangedgroup | |
232 | |
233 # record sublevels for future generations (iterations, that is) | |
234 for name in self.lastsublevels: | |
235 self.lastsublevels[name] = self.scalelevels[name] | |
236 | |
237 # merge effects together | |
238 levels = [0] * 68 | |
239 if changedeffect: | |
240 levels = [int(max(changedeffect.get(ch, 0), | |
241 self.unchangedeffect.get(ch, 0))) | |
242 for ch in range(0, 68)] | |
243 else: | |
244 levels = [int(self.unchangedeffect.get(ch, 0)) | |
245 for ch in range(0, 68)] | |
246 | |
247 ''' | |
248 newend = time() | |
249 | |
250 levels_opt = levels | |
251 | |
252 oldstart = time() | |
253 # i tried to optimize this to a dictionary, but there was no speed | |
254 # improvement | |
255 levels = [0] * 68 | |
256 for name, s in Subs.subs.items(): | |
257 sublevel = self.scalelevels[name].get() | |
258 newlevels = s.get_levels(level=sublevel) | |
259 self.lastsublevels[name] = sublevel # XXX remove | |
260 for (ch, fadelev) in newlevels.items(): | |
261 levels[ch-1] = max(levels[ch-1], fadelev) | |
262 levels = [int(l) for l in levels] | |
263 oldend = time() | |
264 | |
265 newtime = newend - newstart | |
266 oldtime = oldend - oldstart | |
267 print "new", newtime, 'old', (oldend - oldstart), 'sup', \ | |
268 oldtime / newtime | |
269 | |
270 if levels != levels_opt: | |
271 raise "not equal" | |
272 # for l, lo in zip(levels, levels_opt): | |
273 # print l, lo | |
274 ''' | |
74 | 275 |
72 | 276 for lev,lab,oldlev,numlab in zip(levels, self.channel_levels, |
0 | 277 self.oldlevels, |
72 | 278 self.leveldisplay.number_labels): |
0 | 279 if lev != oldlev: |
62
2f2eb802e93d
stage shows levels now. aims have blue halo for easy recognition.
dmcc
parents:
61
diff
changeset
|
280 lab.config(text="%d" % lev) # update labels in lev display |
2f2eb802e93d
stage shows levels now. aims have blue halo for easy recognition.
dmcc
parents:
61
diff
changeset
|
281 colorlabel(lab) # recolor labels |
0 | 282 if lev < oldlev: |
283 numlab['bg'] = 'blue' | |
284 else: | |
285 numlab['bg'] = 'red' | |
286 else: | |
102 | 287 numlab['bg'] = 'grey40' |
0 | 288 |
107 | 289 # replace the elements in oldlevels - don't make a new list |
290 # (Subediting is watching it) | |
291 self.oldlevels[:] = levels[:] | |
0 | 292 |
74 | 293 if self.jostle_mode: |
294 delta = random.randrange(-1, 2, 1) # (-1, 0, or 1) | |
295 # print "delta", delta | |
296 levels = [min(100, max(x + delta, 0)) for x in levels] | |
297 # print "jostled", levels | |
298 | |
119 | 299 dmxclient.outputlevels([l/100 for l in levels]) |
112
afbdae5e1359
dmx light output is now via a separate process which light8 talks to.
drewp
parents:
107
diff
changeset
|
300 # self.parportdmx.sendlevels(levels) |
0 | 301 |
62
2f2eb802e93d
stage shows levels now. aims have blue halo for easy recognition.
dmcc
parents:
61
diff
changeset
|
302 def updatestagelevels(self): |
2f2eb802e93d
stage shows levels now. aims have blue halo for easy recognition.
dmcc
parents:
61
diff
changeset
|
303 self.master.after(100, self.updatestagelevels) |
2f2eb802e93d
stage shows levels now. aims have blue halo for easy recognition.
dmcc
parents:
61
diff
changeset
|
304 for lev, idx in zip(self.oldlevels, xrange(0, 68 + 1)): |
2f2eb802e93d
stage shows levels now. aims have blue halo for easy recognition.
dmcc
parents:
61
diff
changeset
|
305 self.stage.updatelightlevel(Patch.get_channel_name(idx + 1), lev) |
2f2eb802e93d
stage shows levels now. aims have blue halo for easy recognition.
dmcc
parents:
61
diff
changeset
|
306 |
0 | 307 def load(self): |
308 try: | |
309 filename = '/tmp/light9.prefs' | |
310 if self.DUMMY: | |
311 filename += '.dummy' | |
102 | 312 print "Light 8.8: Loading from", filename |
0 | 313 file = open(filename, 'r') |
314 p = cPickle.load(file) | |
315 for s, v in p.scalelevels.items(): | |
316 try: | |
317 self.scalelevels[s].set(v) | |
318 except Exception,e: | |
319 print "Couldn't set %s -> %s: %s" % (s, v,e) | |
320 for name, substate in p.substate.items(): | |
321 try: | |
322 Subs.subs[name].set_state(substate) | |
323 except Exception, e: | |
324 print "Couldn't set sub %s state: %s" % (name,e) | |
325 except IOError, e: | |
326 print "IOError: Couldn't load prefs (%s): %s" % (filename,e) | |
327 except EOFError, e: | |
328 print "EOFrror: Couldn't load prefs (%s): %s" % (filename,e) | |
329 except Exception,e: | |
330 print "Couldn't load prefs (%s): %s" % (filename,e) | |
78
0969d8a6729d
support for external sliders. fill in ExternalInput with real IO
dmcc
parents:
74
diff
changeset
|
331 self.slidermapper.setup() |
0 | 332 |
333 def backgroundloop(self, *args): | |
131 | 334 self.master.after(150, self.backgroundloop, ()) |
0 | 335 self.changelevel() |
336 def quit(self, *args): | |
103
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
337 print "Light 8.8: And that's my cue to exit..." |
0 | 338 self.save() |
103
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
339 self.record_end() |
0 | 340 self.master.destroy() |
341 sys.exit() | |
342 def save(self, *args): | |
343 filename = '/tmp/light9.prefs' | |
344 if self.DUMMY: | |
345 filename += '.dummy' | |
103
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
346 print "Light 8.8: Saving to", filename |
0 | 347 file = open(filename, 'w') |
67 | 348 |
0 | 349 try: |
350 cPickle.dump(Pickles(self.scalelevels, Subs.subs.items()), file) | |
351 except cPickle.UnpickleableError: | |
352 print "UnpickleableError! There's yer problem." | |
74 | 353 def toggle_jostle(self, *args): |
354 self.jostle_mode = not self.jostle_mode | |
107 | 355 if self.jostle_mode: |
356 print 'Light 8.8: Perhaps we can jost-le your memory?' | |
357 else: | |
358 print 'Light 8.8: He remembers! (jostle off)' | |
359 def nonzerosubs(self, *args): | |
360 print "Light 8.8: Active subs:" | |
361 for n, dv in self.scalelevels.items(): | |
362 if dv.get() > 0: | |
363 print "%-.4f: %s" % (dv.get(), n) | |
103
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
364 def record_start(self): |
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
365 print "Light 8.8: Recorder started" |
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
366 self.rec_file.write("%s:\t%s\n" % (time(), "--- Start ---")) |
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
367 self.record_stamp() |
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
368 def record_end(self): |
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
369 print "Light 8.8: Recorder shutdown" |
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
370 self.rec_file.write("%s:\t%s\n" % (time(), "--- End ---")) |
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
371 def record_stamp(self): |
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
372 'Record the current submaster levels, continue this loop' |
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
373 levels = [] |
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
374 for n, v in self.scalelevels.items(): |
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
375 lev = v.get() |
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
376 if lev: |
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
377 levels.append('%s\t%s' % (n, lev)) |
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
378 |
104
15ead14b4dd1
result of 7.13 performance, some ExtSliderMapper fixes
dmcc
parents:
103
diff
changeset
|
379 |
15ead14b4dd1
result of 7.13 performance, some ExtSliderMapper fixes
dmcc
parents:
103
diff
changeset
|
380 newdata = '\t'.join(levels) |
15ead14b4dd1
result of 7.13 performance, some ExtSliderMapper fixes
dmcc
parents:
103
diff
changeset
|
381 if newdata!=self.lastline: |
15ead14b4dd1
result of 7.13 performance, some ExtSliderMapper fixes
dmcc
parents:
103
diff
changeset
|
382 template = "%s:\t%s\n" % (time(), newdata) |
15ead14b4dd1
result of 7.13 performance, some ExtSliderMapper fixes
dmcc
parents:
103
diff
changeset
|
383 self.rec_file.write(template) |
15ead14b4dd1
result of 7.13 performance, some ExtSliderMapper fixes
dmcc
parents:
103
diff
changeset
|
384 self.lastline = newdata |
103
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
385 self.master.after(100, self.record_stamp) |
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
386 def highlight_sub(self, name, color): |
ddd3c8f04640
more untested code, ready for production: colors for slider mapping
dmcc
parents:
102
diff
changeset
|
387 self.subediting.colorsub(name, color) |