changeset 80:5f0c6bc8e9de

for my next trick, i'll object-ize this properly
author dmcc
date Fri, 12 Jul 2002 10:39:21 +0000
parents 233fe8cefa36
children 70bd142d72c2
files light8/ExtSliderMapper.py
diffstat 1 files changed, 73 insertions(+), 284 deletions(-) [+]
line wrap: on
line diff
--- a/light8/ExtSliderMapper.py	Fri Jul 12 10:38:25 2002 +0000
+++ b/light8/ExtSliderMapper.py	Fri Jul 12 10:39:21 2002 +0000
@@ -1,204 +1,16 @@
-""" The External Slider Mapping widget determines which pots map to which
-submasters.  It tells you the status of each mapping and saves and loads
-presets.  The show is relying on this module!  Do not lose it!
-
-FUQ (frequently unasked question(s))
-
-1. What's with all the *args?
-
-It lets functions take any number of arguments and throw them away.
-Callbacks do this, and we typically don't care about what they have to say. """
-
+"""some more of the panels"""
 from Tix import *
-from uihelpers import FancyDoubleVar, get_selection
-
-stdfont = ('Arial', 8)
-colors = ('lightBlue', 'lightPink', 'lightGreen', 'aquamarine1')
-
-class SliderMapping:
-    def __init__(self, color, default='disconnected', synced=0, 
-                 extinputlevel=0, sublevel=0):
-        self.color = color
-        self.subname = StringVar() # name of submaster we're connected to
-        self.subname.set(default)
-        self.sublevel = DoubleVar() # scalelevel variable of that submaster
-        # self.sublevel = FancyDoubleVar() # scalelevel variable of that submaster
-        self.sublevel.set(sublevel)
-        self.synced = BooleanVar() # currently synced
-        self.synced.set(synced)
-        self.extlevel = DoubleVar() # external slider's input
-        self.extlevel.set(extinputlevel)
-        self.widgets = [] # list of widgets drawn
-        self.sublabel = None # the label which represents a sub level.  
-                             # we hold on to it so we can change its 
-                             # textvariable
-        self.statuslabel = None # tells us sync status
-        self.lastbgcolor = None # last background color drawn to avoid 
-                                # unnecessary redraws
-        self.subnames = [] # we need to keep track of this for idiotic reasons
-    def sync(self, *args):
-        self.synced.set(1)
-        self.color_bg()
-    def unsync(self, *args):
-        self.synced.set(0)
-        self.color_bg()
-    def issynced(self):
-        return self.synced.get()
-    def disconnect(self, *args):
-        self.set_subname('disconnected') # a bit hack-like
-        # self.sublevel.delete_named('sync')
-        '''
-        try:
-            if self.sublevel.unsync_trace_cbname is not None:
-                # self.sublevel.trace_vdelete('w', 
-                    # self.sublevel.unsync_trace_cbname)
-                self.sublevel._tk.call('trace', 'vdelete', self.sublevel._name, 
-                    'w', self.sublevel.unsync_trace_cbname)
-                self.sublevel.unsync_trace_cbname = None
-        except AttributeError:
-            pass
-        '''
-            
-        self.sublabel.configure(text="N/A")
-        self.color_bg()
-    def isdisconnected(self):
-        return self.subname.get() == 'disconnected' # a bit more hack-like
-    def check_synced(self, *args):
-        'If external level is near than the sublevel, it synces'
-        if self.isdisconnected(): 
-            self.unsync()
-            return
-
-        if abs(self.extlevel.get() - self.sublevel.get()) <= 0.02:
-            self.sync()
-    def changed_extinput(self, newlevel):
-        'When a new external level is received, this incorporates it'
-        self.extlevel.set(newlevel)
-        self.check_synced()
-        self.color_bg()
-    def set_subname(self, newname):
-        try:
-            self.listbox.listbox.select_clear(0, END)
-        except IndexError:
-            pass
-        try:
-            newindex = self.subnames.index(newname)
-            self.listbox.listbox.select_set(newindex)
-            self.listbox.listbox.see(newindex)
-        except ValueError:
-            pass
-
-        self.subname.set(newname)
-        self.unsync()
-        self.color_bg()
-    def color_bg(self):
-        if self.widgets:
-            if self.isdisconnected():
-                color = 'honeyDew4'
-            # stupid hack
-            # elif abs(self.extlevel.get() - self.sublevel.get()) <= 0.02:
-            elif self.issynced():
-                color = 'honeyDew2'
-            else: # unsynced
-                color = 'red'
-
-            if self.statuslabel: # more stupid hackery
-                if color == 'honeyDew2': # connected
-                    self.statuslabel['text'] = 'Sync'
-                elif self.extlevel.get() < self.sublevel.get():
-                    self.statuslabel['text'] = 'No sync (go up)'
-                else:
-                    self.statuslabel['text'] = 'No sync (go down)'
-
-            # print "color", color, "lastbgcolor", self.lastbgcolor
-            if self.lastbgcolor == color: return
-            for widget in self.widgets:
-                widget.configure(bg=color)
-            self.lastbgcolor = color
-    def set_sublevel_var(self, newvar):
-        'newvar is one of the variables in scalelevels'
-
-        if newvar is not self.sublevel:
-            # self.sublevel.delete_named('sync')
-            self.sublevel = newvar
-            self.sublabel.configure(textvariable=newvar)
-            # self.sublevel.trace_named('sync', lambda *args: self.unsync(*args))
-            '''
-            try:
-                if self.sublevel.unsync_trace_cbname is not None:
-                    # remove an old trace
-                    self.sublevel.trace_vdelete('w',
-                        self.sublevel.unsync_trace_cbname)
-            except AttributeError:
-                pass # it didn't have one
-
-            self.sublevel = newvar
-            self.sublevel.unsync_trace_cbname = self.sublevel.trace('w', 
-                self.unsync)
-            '''
-
-        # if self.sublabel:
-            # self.sublabel.configure(textvariable=newvar)
-        self.check_synced()
-    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 listbox_cb(self, *args):
-        selection = get_selection(self.listbox.listbox)
-        self.disconnect()
-        self.subname.set(self.subnames[selection])
-        self.listbox.listbox.select_set(selection)
-    def draw_interface(self, master, subnames):
-        'Draw interface into master, given a list of submaster names'
-        self.subnames = subnames
-        frame = Frame(master, bg='black')
-        self.listbox = ScrolledListBox(frame, scrollbar='y', bg='black')
-        self.listbox.listbox.bind("<<ListboxSelect>>", self.listbox_cb, add=1)
-        self.listbox.listbox.configure(font=stdfont, exportselection=0, 
-            selectmode=BROWSE, bg='black', fg='white', 
-            selectbackground=self.color)
-        self.listbox.vsb.configure(troughcolor=self.color)
-        # self.listbox.listbox.insert(END, "disconnected")
-        for s in subnames:
-            self.listbox.listbox.insert(END, s)
-        statframe = Frame(frame, bg='black')
-
-        self.statuslabel = Label(statframe, text="No sync", width=15, 
-            font=stdfont)
-        self.statuslabel.grid(columnspan=2, sticky=W)
-        ilabel = Label(statframe, text="Input", fg='blue', font=stdfont)
-        ilabel.grid(row=1, sticky=W)
-        extlabel = Label(statframe, textvariable=self.extlevel, width=5, 
-            font=stdfont)
-        extlabel.grid(row=1, column=1)
-        rlabel = Label(statframe, text="Real", font=stdfont)
-        rlabel.grid(row=2, sticky=W)
-        self.sublabel = Label(statframe, text="N/A", width=5, font=stdfont)
-        self.sublabel.grid(row=2, column=1)
-        disc_button = Button(statframe, text="Disconnect", 
-            command=self.disconnect, padx=0, pady=0, font=stdfont)
-        disc_button.grid(row=3, columnspan=2)
-        statframe.pack(side=BOTTOM, expand=1, fill=BOTH)
-        self.listbox.pack(expand=1, fill=BOTH)
-        frame.pack(side=LEFT, expand=1, fill=BOTH)
-
-        self.widgets = [frame, self.listbox, statframe, self.statuslabel, 
-                        ilabel, extlabel, rlabel, self.sublabel, disc_button]
 
 class ExtSliderMapper(Frame):
-    def __init__(self, parent, sliderlevels, sliderinput, 
-                 lightboard, filename='slidermapping', numsliders=4):
+    def __init__(self, parent, sliderlevels, sliderinput, filename='slidermapping',
+                 numsliders=4):
         'Slider levels is scalelevels, sliderinput is an ExternalInput object'
-        Frame.__init__(self, parent, bg='black')
+        Frame.__init__(self, parent)
         self.parent = parent
         self.sliderlevels = sliderlevels
         self.sliderinput = sliderinput
         self.filename = filename
         self.numsliders = numsliders
-        self.lightboard = lightboard
         self.file = None
 
         # don't call setup, let them do that when scalelevels is created
@@ -208,14 +20,20 @@
         self.presets = {}
         self.load_presets()
 
-        self.current_preset = StringVar() # name of current preset
-        self.current_mappings = []
-        for i, color in zip(range(self.numsliders), colors):
-            self.current_mappings.append(SliderMapping(color))
+        self.current_mapping_name = StringVar()
+        self.current_mapping = []
+        self.attached = []
+        self.levels_read = []
+        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.reallevellabels = []
         self.draw_interface()
-    def load_presets(self, *args):
-        self.presets = {}
+    def load_presets(self):
         self.file = open(self.filename, 'r')
         lines = self.file.readlines()
         for l in lines:
@@ -223,8 +41,6 @@
             name = tokens.pop(0)
             self.presets[name] = tokens
         self.file.close()
-        if args: # called from callback
-            self.draw_interface()
     def save_presets(self):
         self.file = open(self.filename, 'w')
         self.file.seek(0)
@@ -235,119 +51,92 @@
             self.file.write(s)
         self.file.close()
     def load_scalelevels(self):
-        for slidermap in self.current_mappings:
+        for m, rll, levread, att in zip(self.current_mapping, self.reallevellabels, 
+                                        self.levels_read, self.attached):
             try:
-                v = self.sliderlevels[slidermap.get_mapping()]
-                slidermap.set_sublevel_var(v)
-                # print "ESM: Yes submaster named", slidermap.get_mapping()
+                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)
             except KeyError:
-                name = slidermap.get_mapping()
-                if name != 'disconnected':
-                    print "ESM: No submaster named", name
+                pass
                 
     def get_levels(self):
-        'Called by changelevels, returns a dict of new values for submasters'
+        'To be called by changelevels, I think'
+        if not self.current_mapping_name: return {}
         if not self.sliderinput: return {}
 
-        self.load_scalelevels() # freshen our input from the submasters
-
-        for m, color in zip(self.current_mappings, colors):
-            name = m.get_mapping()
-            lastsub = self.subs_highlighted.get(color)
-            if name is not lastsub:
-                if lastsub is not None:
-                    try: 
-                        self.lightboard.highlight_sub(lastsub, 'restore')
-                    except KeyError:
-                        pass
-                try:
-                    self.lightboard.highlight_sub(name, color)
-                except KeyError:
-                    pass
-                self.subs_highlighted[color] = name
+        self.load_scalelevels()
 
         rawlevels = self.sliderinput.get_levels()
-        for rawlev, slidermap in zip(rawlevels, self.current_mappings):
-            slidermap.changed_extinput(rawlev)
+        for rawlev, levlabvar in zip(rawlevels, self.levels_read):
+            levlabvar.set(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.issynced()])
     def draw_interface(self):
-        self.subs_highlighted = {}
-        subchoiceframe = Frame(self, bg='black')
-        for m in self.current_mappings:
-            m.draw_interface(subchoiceframe, self.subnames)
+        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)
         subchoiceframe.pack()
         
-        presetframe = Frame(self, bg='black')
-        Label(presetframe, text="Preset:", font=('Arial', 10), bg='black', 
-            fg='white').pack(side=LEFT)
-        self.presetcombo = ComboBox(presetframe, variable=self.current_preset, 
-                                    editable=1, command=self.apply_preset,
-                                    dropdown=1)
-        self.presetcombo.slistbox.configure(bg='black')
-        self.presetcombo.slistbox.listbox.configure(bg='black', fg='white')
-        self.presetcombo.entry.configure(bg='black', fg='white')
+        presetframe = Frame(self)
+        Label(presetframe, text="Preset:").pack(side=LEFT)
+        self.presetcombo = ComboBox(presetframe, variable=self.current_mapping_name, 
+                                    editable=1, command=self.apply_preset)
         self.draw_presets()
         self.presetcombo.pack(side=LEFT)
-        Button(presetframe, text="Prev", padx=0, pady=0, bg='black', 
-                fg='white', font=stdfont, 
-                command=self.prev_preset).pack(side=LEFT)
-        Button(presetframe, text="Next", padx=0, pady=0, bg='black', 
-                fg='white', font=stdfont, 
-                command=self.next_preset).pack(side=LEFT)
-        Button(presetframe, text="Add", padx=0, pady=0, bg='black', 
-                fg='white', font=stdfont, 
+        Button(presetframe, text="Add", padx=0, pady=0, 
                 command=self.add_preset).pack(side=LEFT)
-        Button(presetframe, text="Delete", padx=0, pady=0, bg='black', 
-                fg='white', font=stdfont,
+        Button(presetframe, text="Delete", padx=0, pady=0, 
                 command=self.delete_preset).pack(side=LEFT)
-        Button(presetframe, text="Disconnect", padx=0, pady=0, bg='black', 
-                fg='white', font=stdfont,
-                command=self.disconnect_all).pack(side=LEFT)
-        Button(presetframe, text="Reload", padx=0, pady=0, bg='black', 
-                fg='white', font=stdfont,
-                command=self.load_presets).pack(side=LEFT)
         presetframe.pack(side=BOTTOM)
     def apply_preset(self, preset):
         if not preset: return
-        preset_mapping = self.presets.get(preset)
-        if not preset_mapping: return
-        self.disconnect_all()
-        for subname, slidermap in zip(preset_mapping, self.current_mappings):
-            slidermap.set_subname(subname)
-    def change_preset_by_index(self, delta):
-        preset_names = self.presets.keys()
-        preset_names.sort()
-        try:
-            next = preset_names[preset_names.index(self.current_preset.get())
-                + delta]
-            self.current_preset.set(next)
-            self.apply_preset(next)
-        except (IndexError, ValueError):
-            print "Light 8.8: Can't go in that direction.  Dig up!"
-    def next_preset(self, *args):
-        self.change_preset_by_index(1)
-    def prev_preset(self, *args):
-        self.change_preset_by_index(-1)
+        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
     def delete_preset(self, *args):
-        del self.presets[self.current_preset.get()]
+        del self.presets[self.current_mapping_name.get()]
         self.presetcombo.slistbox.listbox.delete(0, END)
         self.draw_presets()
         self.save_presets()
     def add_preset(self, *args):
-        self.presets[self.current_preset.get()] = [m.get_mapping() 
-                for m in self.current_mappings]
+        self.presets[self.current_mapping_name.get()] = [m.get() 
+                for m in self.current_mapping]
         self.presetcombo.slistbox.listbox.delete(0, END)
         self.draw_presets()
         self.save_presets()
-        self.draw_interface()
     def draw_presets(self):
         preset_names = self.presets.keys()
         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()