Changeset - 83e2c4ceb79a
[Not reviewed]
default
0 4 0
dmcc - 22 years ago 2003-06-14 16:19:40

KeyboardComposer: let's get it working again
KeyboardComposer: let's get it working again
TheShow: get_timelines method
Timeline: it's late, okay?
TimelineDMX: timeline selector, basically copied from that music player
thing
4 files changed with 28 insertions and 17 deletions:
0 comments (0 inline, 0 general)
flax/KeyboardComposer.py
Show inline comments
 
@@ -168,49 +168,49 @@ class KeyboardComposer(Frame):
 
        row = self.rows[row]
 
        row['bg'] = 'red'
 
    def unhighlight_row(self, row):
 
        row = self.rows[row]
 
        row['bg'] = '#d9d9d9'
 
    def get_levels(self):
 
        return dict([(name, slidervar.get()) 
 
            for name, slidervar in self.slider_vars.items()])
 
    def get_dmx_list(self):
 
        scaledsubs = [self.submasters.get_sub_by_name(sub) * level \
 
            for sub, level in self.get_levels().items()]
 

	
 
        maxes = sub_maxes(*scaledsubs)
 
        return maxes.get_dmx_list()
 
    def save(self):
 
        pickle.dump(self.get_levels(), 
 
                    file('.keyboardcomposer.savedlevels', 'w'))
 
    def send_frequent_updates(self):
 
        """called when we get a fade -- send events as quickly as possible"""
 
        if time.time() <= self.stop_frequent_update_time:
 
            self.send_levels()
 
            self.after(10, self.send_frequent_updates)
 
    def send_levels(self):
 
        levels = self.get_dmx_list()
 
        # dmxclient.outputlevels(levels)
 
        dmxclient.outputlevels(levels)
 
        # print "sending levels", levels
 
    def send_levels_loop(self):
 
        self.send_levels()
 
        self.after(1000, self.send_levels_loop)
 
    def refresh(self):
 
        self.save()
 
        self.submasters = Submasters()
 
        self.current_sub_levels = \
 
            pickle.load(file('.keyboardcomposer.savedlevels'))
 
        for r in self.rows:
 
            r.destroy()
 
        self.keyhints.destroy()
 
        self.refreshbutton.destroy()
 
        self.draw_ui()
 

	
 
if __name__ == "__main__":
 
    s = Submasters()
 

	
 
    root = Tk()
 
    tl = toplevelat("Keyboard Composer", existingtoplevel=root)
 
    kc = KeyboardComposer(tl, s)
 
    kc.pack(fill=BOTH, expand=1)
 
    atexit.register(kc.save)
 
    try:
flax/TheShow.py
Show inline comments
 

	
 

	
 
from Timeline import *
 
from Submaster import Submasters, sub_maxes
 

	
 
class Show:
 
    def __init__(self, timelines, submasters):
 
        self.timelines = dict([(timeline.name, timeline)
 
            for timeline in timelines])
 
        self.submasters = submasters
 
        self.current_timeline = None
 
        self.current_time = 0
 
        try:
 
            self.current_timeline = timelines[0]
 
        except ValueError:
 
            pass
 
    def calc_active_submaster(self):
 
        "get levels from the current timeline at the current time"
 
        if not (self.current_timeline or self.current_time):
 
            return {}
 
        tl = self.current_timeline
 
        tl.set_time(self.current_time)
 
        levels = tl.get_levels()
 
        scaledsubs = [self.submasters.get_sub_by_name(sub) * level \
 
            for sub, level in levels.items()]
 
        maxes = sub_maxes(*scaledsubs)
 

	
 
        return maxes
 
    def set_timeline(self, name):
 
        "select a timeline"
 
        self.current_timeline = self.timelines.get(name)
 
        self.set_time(0)
 
        if not self.current_timeline:
 
            print "Show: '%s' is not the same of a timeline."
 
    def set_time(self, time):
 
        "set time of current timeline"
 
        self.current_time = time
 
        self.current_timeline.set_time(time)
 
    def get_timelines(self):
 
        "Get names of all timelines"
 
        return self.timelines.keys()
 

	
 
# this is the default blender
 
linear = LinearBlender()
 
def T(time, level, **kw):
 
    """This used to be a synonym for TimedEvent:
 

	
 
    T = TimedEvent
 

	
 
    It now acts in a similar way, except that it will fill in a default 
 
    blender if you don't.  The default blender is a LinearBlender.  It also
 
    sets frame to MISSING so the track can fill it in."""
 
    if 'blender' not in kw:
 
        global linear
 
        kw['blender'] = linear
 

	
 
    return TimedEvent(time, level=level, frame=MISSING, **kw)
 

	
 
quad = ExponentialBlender(2)
 
invquad = ExponentialBlender(0.5)
 
smoove = SmoothBlender()
 

	
 
track1 = TimelineTrack('red track',
 
    T(0, 0),
 
    T(4, 0.5, blender=quad),
flax/Timeline.py
Show inline comments
 
@@ -147,69 +147,69 @@ class Strobe(Blender):
 
            return {endframe.frame : self.onlevel}
 
        else:
 
            return {endframe.frame : self.offlevel}
 

	
 
class TimelineTrack:
 
    """TimelineTrack is a single track in a Timeline.  It consists of a
 
    list of TimedEvents and a name.  Length is automatically the location
 
    of the last TimedEvent.  To extend the Timeline past that, add an
 
    EmptyTimedEvent (which doesn't exist :-/)."""
 
    def __init__(self, name, *timedevents, **kw):
 
        if kw.get('default_frame'):
 
            self.default_frame = kw['default_frame']
 
        else:
 
            self.default_frame = None
 
        self.name = name
 
        self.set_events(list(timedevents))
 
    def set_events(self, events):
 
        """This is given a list of TimedEvents.  They need not be sorted."""
 
        self.events = events
 
        self._cleaup_events()
 
    def _cleaup_events(self):
 
        """This makes sure all events are in the right order and have defaults
 
        filled in if they have missing frames."""
 
        self.events.sort()
 
        self.fill_in_missing frames()
 
        self.fill_in_missing_frames()
 
    def add_event(self, event):
 
        """Add a TimedEvent object to this TimelineTrack"""
 
        self.events.append(event)
 
        self._cleaup_events(self.events)
 
    def delete_event(self, event):
 
        """Delete event by TimedEvent object"""
 
        self.events.remove(event)
 
        self._cleaup_events(self.events)
 
    def delete_event_by_name(self, name):
 
        """Deletes all events matching a certain name"""
 
        self.events = [e for e in self.events if e.name is not name]
 
        self._cleaup_events(self.events)
 
    def delete_event_by_time(self, starttime, endtime=None):
 
        """Deletes all events within a certain time range, inclusive.  endtime
 
        is optional."""
 
        endtime = endtime or starttime
 
        self.events = [e for e in self.events
 
            if e.time >= starttime and e.time <= endtime]
 
        self._cleaup_events(self.events)
 
    def fill_in_missing frames(self):
 
    def fill_in_missing_frames(self):
 
        """Runs through all events and sets TimedEvent with missing frames to
 
        the default frame."""
 
        for event in self.events:
 
            if event.frame == MISSING:
 
                event.frame = self.default_frame
 
    def __str__(self):
 
        return "<TimelineTrack with events: %r>" % self.events
 
    def has_events(self):
 
        """Whether the TimelineTrack has anything in it.  In general,
 
        empty level Tracks should be avoided.  However, empty function tracks
 
        might be common."""
 
        return len(self.events)
 
    def length(self):
 
        """Returns the length of this track in pseudosecond time units.
 
        This is done by finding the position of the last TimedEvent."""
 
        return float(self.events[-1])
 
    def get(self, key, direction=FORWARD):
 
        """Returns the event at a specific time key.  If there is no event
 
        at that time, a search will be performed in direction.  Also note
 
        that if there are multiple events at one time, only the first will
 
        be returned.  (Probably first in order of adding.)  This is not
 
        a problem at the present since this method is intended for LevelFrames,
 
        which must exist at unique times."""
 
        if direction == BACKWARD:
flax/TimelineDMX.py
Show inline comments
 
import sys, time, socket
 
sys.path.append("../light8")
 
import Tix as tk
 

	
 
import Patch, Timeline, dmxclient, xmlrpclib
 
import TheShow
 

	
 
Patch.reload_data()
 

	
 
class ShowRunner:
 
    def __init__(self, show):
 
class ShowRunner(tk.Frame):
 
    def __init__(self, master, show):
 
        tk.Frame.__init__(self, master)
 
        self.master = master
 

	
 
        self.show = show
 
        self.find_player()
 
        self.build_timeline_list()
 
    def build_timeline_list(self):
 
        self.tl_list = tk.Frame(self)
 
        for tl in self.show.get_timelines():
 
            b=tk.Button(self.tl_list,text=tl,
 
                        anchor='w',pady=1)
 
            b.config(command=lambda tl=tl: self.set_timeline(tl))
 
            b.pack(side='top',fill='x')
 
        self.tl_list.pack()
 
    def set_timeline(self, tlname):
 
        print "TimelineDMX: set timeline to", tlname
 
        self.show.set_timeline(tlname)
 
    def find_player(self):
 
        self.player = xmlrpclib.Server("http://localhost:8040")
 
    def send_levels(self):
 
        """
 
        sub = self.show.get_levels() # gets levels of subs
 
        leveldict = sub.get_levels() # gets levels of sub contents
 
        print 'resolved levels', leveldict
 

	
 
        levels = [0] * 68
 
        for k, v in leveldict.items():
 
            levels[Patch.get_dmx_channel(k)] = v
 
        """
 
        levels = self.show.calc_active_submaster().get_dmx_list()
 
        
 
        dmxclient.outputlevels(levels)
 
    def sync_times(self):
 
        try:
 
            playtime = self.player.gettime()
 
            self.show.set_time(playtime)
 
        except socket.error, e:
 
            print "Server error %s, waiting"%e
 
            time.sleep(2)
 
    def mainloop(self):
 
        try:
 
            while 1:
 
                self.sync_times()
 
                self.send_levels()
 
                time.sleep(0.01)
 
                self.master.update()
 
        except KeyboardInterrupt:
 
            sys.exit(0)
 

	
 
if __name__ == "__main__":
 
    s = ShowRunner(TheShow.show)
 
    root = tk.Tk()
 
    s = ShowRunner(root, TheShow.show)
 
    s.show.set_timeline('strobe test')
 
    s.pack()
 
    s.mainloop()
0 comments (0 inline, 0 general)