diff --git a/light8/ExtSliderMapper.py b/light8/ExtSliderMapper.py --- a/light8/ExtSliderMapper.py +++ b/light8/ExtSliderMapper.py @@ -1,6 +1,91 @@ """some more of the panels""" from Tix import * +class SliderMapping: + def __init__(self, default='disconnected', attached=0, extinputlevel=0, + sublevel=0): + self.subname = StringVar() # name of submaster we're connected to + self.subname.set(default) + self.sublevel = DoubleVar() # scalelevel variable of that submaster + self.sublevel.set(sublevel) + self.attached = BooleanVar() # currently attached + self.attached.set(attached) + self.extlevel = DoubleVar() # external slider's input + self.extlevel.set(extinputlevel) + self.extlabel = None + self.sublabel = None + def attach(self): + self.attached.set(1) + self.color_text() + def detach(self): + self.attached.set(0) + self.color_text() + def isattached(self): + return self.attached.get() + def isdisconnected(self): + return self.subname.get() == 'disconnected' + def check_attached(self): + 'If external level is higher than the sublevel, it attaches' + if self.isdisconnected(): + self.detach() + return + + if self.extlevel.get() > self.sublevel.get(): + self.attached.set(1) + self.color_text() + def changed_extinput(self, newlevel): + 'When a new external level is received, this incorporates it' + self.extlevel.set(newlevel) + self.check_attached() + self.color_text() + def set_subname(self, newname): + self.subname.set(newname) + self.detach() + self.color_text() + def color_text(self): + if self.extlabel: + if self.isdisconnected(): + self.extlabel.configure(fg='honeyDew4') + elif self.isattached(): + self.extlabel.configure(fg='honeyDew2') + else: + self.extlabel.configure(fg='red') + def disconnect(self): + self.set_subname('disconnected') # a bit hack-like + self.sublabel.configure(text="N/A") + def set_sublevel_var(self, newvar): + 'newvar is one of the variables in scalelevels' + self.sublevel = newvar + if self.sublabel: + self.sublabel.configure(textvariable=newvar) + self.check_attached() + def get_mapping(self): + 'Get name of submaster currently mapped' + return self.subname.get() + def get_level_pair(self): + 'Returns suitable output for ExtSliderMapper.get_levels()' + return (self.subname.get(), self.extlevel.get()) + def draw_interface(self, master, subnames): + 'Draw interface into master, given a list of submaster names' + frame = Frame(master) + c = ComboBox(frame, variable=self.subname) + c.slistbox.listbox.insert(END, "disconnected") + for s in subnames: + c.slistbox.listbox.insert(END, s) + c.entry.configure(width=12) + statframe = Frame(frame) + Checkbutton(statframe, variable=self.attached, + text="Attached").grid(columnspan=2, sticky=W) + Label(statframe, text="Input", fg='red').grid(row=1, sticky=W) + self.extlabel = Label(statframe, textvariable=self.extlevel, width=5) + self.extlabel.grid(row=1, column=1) + Label(statframe, text="Real").grid(row=2, sticky=W) + self.sublabel = Label(statframe, text="N/A", width=5) + self.sublabel.grid(row=2, column=1) + statframe.pack(side=BOTTOM, expand=1, fill=X) + c.pack() + frame.pack(side=LEFT, expand=1, fill=BOTH) + class ExtSliderMapper(Frame): def __init__(self, parent, sliderlevels, sliderinput, filename='slidermapping', numsliders=4): @@ -20,18 +105,11 @@ class ExtSliderMapper(Frame): self.presets = {} self.load_presets() - self.current_mapping_name = StringVar() - self.current_mapping = [] - self.attached = [] - self.levels_read = [] + self.current_preset = StringVar() # name of current preset + self.current_mappings = [] for i in range(self.numsliders): - cm_var = StringVar() - cm_var.set('disconnected') - self.current_mapping.append(cm_var) - self.attached.append(BooleanVar()) - self.levels_read.append(DoubleVar()) + self.current_mappings.append(SliderMapping()) - self.reallevellabels = [] self.draw_interface() def load_presets(self): self.file = open(self.filename, 'r') @@ -51,64 +129,37 @@ class ExtSliderMapper(Frame): self.file.write(s) self.file.close() def load_scalelevels(self): - for m, rll, levread, att in zip(self.current_mapping, self.reallevellabels, - self.levels_read, self.attached): + for slidermap in self.current_mappings: try: - v = self.sliderlevels[m.get()] # actual scalelevel variable - rll.configure(textvariable=v) - if levread.get() >= v.get(): # attach if physical goes above virtual - att.set(1) + v = self.sliderlevels[slidermap.get_mapping()] + slidermap.set_sublevel_var(v) except KeyError: pass def get_levels(self): - 'To be called by changelevels, I think' - if not self.current_mapping_name: return {} + 'Called by changelevels, returns a dict of new values for submasters' if not self.sliderinput: return {} - self.load_scalelevels() + self.load_scalelevels() # freshen our input from the physical sliders rawlevels = self.sliderinput.get_levels() - for rawlev, levlabvar in zip(rawlevels, self.levels_read): - levlabvar.set(rawlev) + for rawlev, slidermap in zip(rawlevels, self.current_mappings): + slidermap.changed_extinput(rawlev) + outputlevels = {} - return dict([(name.get(), lev) - for name, lev, att in zip(self.current_mapping, - rawlevels, - self.attached) - if att.get()]) - + return dict([m.get_level_pair() + for m in self.current_mappings + if m.isattached()]) def draw_interface(self): self.reallevellabels = [] subchoiceframe = Frame(self) - for i, mapping, isattached, lev in zip(range(self.numsliders), - self.current_mapping, - self.attached, - self.levels_read): - f = Frame(subchoiceframe) - # Label(f, text="Slider %d" % (i+1)).pack(side=LEFT) - c = ComboBox(f, variable=mapping) - c.slistbox.listbox.insert(END, "disconnected") - for s in self.subnames: - c.slistbox.listbox.insert(END, s) - c.entry.configure(width=12) - statframe = Frame(f) - Checkbutton(statframe, variable=isattached, - text="Attached").grid(columnspan=2, sticky=W) - Label(statframe, text="Input", fg='red').grid(row=1, sticky=W) - Label(statframe, textvariable=lev, fg='red', width=5).grid(row=1, column=1) - Label(statframe, text="Real").grid(row=2, sticky=W) - l = Label(statframe, text="N/A", width=5) - l.grid(row=2, column=1) - self.reallevellabels.append(l) - statframe.pack(side=BOTTOM, expand=1, fill=X) - c.pack() - f.pack(side=LEFT, expand=1, fill=BOTH) + for m in self.current_mappings: + m.draw_interface(subchoiceframe, self.subnames) subchoiceframe.pack() presetframe = Frame(self) Label(presetframe, text="Preset:").pack(side=LEFT) - self.presetcombo = ComboBox(presetframe, variable=self.current_mapping_name, + self.presetcombo = ComboBox(presetframe, variable=self.current_preset, editable=1, command=self.apply_preset) self.draw_presets() self.presetcombo.pack(side=LEFT) @@ -116,22 +167,23 @@ class ExtSliderMapper(Frame): command=self.add_preset).pack(side=LEFT) Button(presetframe, text="Delete", padx=0, pady=0, command=self.delete_preset).pack(side=LEFT) + Button(presetframe, text="Disconnect", padx=0, pady=0, + command=self.disconnect_all).pack(side=LEFT) presetframe.pack(side=BOTTOM) def apply_preset(self, preset): if not preset: return - mapping = self.presets.get(preset) - if not mapping: return - for name, var, att in zip(mapping, self.current_mapping, self.attached): - var.set(name) - att.set(0) # detach all sliders + preset_mapping = self.presets.get(preset) + if not preset_mapping: return + for subname, slidermap in zip(preset_mapping, self.current_mappings): + slidermap.set_subname(subname) def delete_preset(self, *args): - del self.presets[self.current_mapping_name.get()] + del self.presets[self.current_preset.get()] self.presetcombo.slistbox.listbox.delete(0, END) self.draw_presets() self.save_presets() def add_preset(self, *args): - self.presets[self.current_mapping_name.get()] = [m.get() - for m in self.current_mapping] + self.presets[self.current_preset.get()] = [m.get_mapping() + for m in self.current_mappings] self.presetcombo.slistbox.listbox.delete(0, END) self.draw_presets() self.save_presets() @@ -140,3 +192,6 @@ class ExtSliderMapper(Frame): preset_names.sort() for p in preset_names: self.presetcombo.slistbox.listbox.insert(END, p) + def disconnect_all(self): + for m in self.current_mappings: + m.disconnect() diff --git a/light8/slidermapping b/light8/slidermapping --- a/light8/slidermapping +++ b/light8/slidermapping @@ -1,3 +1,5 @@ Disconnect all disconnected disconnected disconnected disconnected colors col blue col gree col oran col red first four *1-01-0 *1-02-0 *1-03-0 *1-04-00-dance +random *1-03-0 *1-04-10-after dance *1-06-0 *1-01-0 +vitals house god *curtain phone booth