changeset 694:34dacd800505

eval loop is running, music drives lights. started to add goocanvas curve view Ignore-this: f30c27eb9d589e350104730e2a926276
author Drew Perttula <drewp@bigasterisk.com>
date Fri, 08 Jun 2012 07:38:46 +0000
parents 810bedfc9a93
children 0b8fc64a896c
files bin/curvecalc light9/curvecalc/curve.py light9/curvecalc/curvecalc.glade light9/curvecalc/curveview.py light9/curvecalc/musicaccess.py light9/curvecalc/output.py light9/curvecalc/subtermview.py
diffstat 7 files changed, 657 insertions(+), 608 deletions(-) [+]
line wrap: on
line diff
--- a/bin/curvecalc	Fri Jun 08 05:12:16 2012 +0000
+++ b/bin/curvecalc	Fri Jun 08 07:38:46 2012 +0000
@@ -10,12 +10,14 @@
 
 """
 from __future__ import division
+
 from twisted.internet import gtk2reactor
-import time,textwrap,os,optparse, urllib2, gtk, gobject
+gtk2reactor.install()
+from twisted.internet import reactor
+
+import time, textwrap, os, optparse, urllib2, gtk, gobject
 import louie as dispatcher 
-
 from twisted.python.util import sibpath
-
 from rdflib import URIRef
 from rdflib import Graph
 import rdflib
@@ -32,28 +34,9 @@
 from light9.uihelpers import toplevelat
 from light9.namespaces import L9
 from light9.curvecalc.subterm import read_all_subs, savekey, graphPathForSubterms
-from light9.curvecalc.subtermview import makeSubtermCommandRow, add_one_subterm
+from light9.curvecalc.subtermview import add_one_subterm
 from light9.curvecalc.output import Output
 
-def makeStatusLines(master):
-    """various labels that listen for dispatcher signals"""
-    for signame,textfilter in [
-        ('input time',lambda t: "%.2fs"%t),
-        ('output levels',
-         lambda levels: textwrap.fill("; ".join(["%s:%.2f"%(n,v)
-                                                 for n,v in
-                                                 levels.items()[:5]
-                                                 if v>0]),70)),
-        ('update period',lambda t: "%.1fms"%(t*1000)),
-        ('update status',lambda t: str(t)),
-        ]:
-        l = tk.Label(master, anchor='w', justify='left', text='%s:' % signame)
-        l.pack(side='top',fill='x')
-        dispatcher.connect(lambda val,l=l,sn=signame,tf=textfilter:
-                           l.config(text=sn+": "+tf(val)),
-                           signame, weak=False)
-
-
 def makeGraph():
     graphOrig = showconfig.getGraph()
     graph = Graph() # a copy, since we're going to add subs into it
@@ -62,62 +45,8 @@
     read_all_subs(graph)
     return graph
 
-def setupKeyBindings(root, song, subterms, curveset):
-    root.bind("<Control-Key-s>",
-              lambda *args: savekey(song, subterms, curveset))
-    root.bind("<Control-Key-r>", lambda evt: dispatcher.send('reload all subs'))
-    root.bind("<Control-Key-n>",
-              lambda evt: dispatcher.send('focus new subterm'))
-    root.bind("<Control-Key-N>", lambda evt: dispatcher.send('focus new curve'))
-    root.bind("<Control-Key-q>",lambda ev: reactor.stop)
-    root.bind("<Destroy>",lambda ev: reactor.stop)
-    root.protocol('WM_DELETE_WINDOW', reactor.stop)
-
-def setupMenubar(barFrame, root, song, subterms, curveset):
-    class newMenu(object):
-        def __init__(self, name):
-            self.name = name
-        def __enter__(self):
-            m = tk.Menubutton(barFrame, text=self.name)
-            m.pack(side='left')
-            mm = tk.Menu(m)
-            m.config(menu=mm)
-            return mm
-        def __exit__(self, type, value, traceback):
-            return False
-        
-    def notImpl(*args):
-        print "sorry, menu command binding isn't done yet. Use the keyboard shortcut"
-        
-    with newMenu("Curvecalc") as m:
-        m.add_command(label='Save', underline=0, accelerator="Ctrl+s",
-                      command=lambda *args: savekey(song, subterms, curveset))
-        m.add_command(label='Quit', command=root.destroy)
-
-    with newMenu("View") as m:
-        m.add_command(label="See current time", accelerator="Esc", command=notImpl)
-        m.add_command(label="See from current time -> end", accelerator="Shift+Esc", command=notImpl)
-        m.add_command(label="Zoom all", accelerator="Ctrl+Esc", command=notImpl)
-        m.add_command(label="Zoom in", accelerator="Wheel up", command=notImpl)
-        m.add_command(label="Zoom out", accelerator="Wheel down", command=notImpl)
-
-    with newMenu("Playback") as m:
-        m.add_command(label="Play/pause at mouse", accelerator="Ctrl+P", command=notImpl)
-
-    with newMenu("Points") as m:
-        m.add_command(label="Delete", accelerator="Del", command=notImpl)
-
-
-def createHelpLines(root):
-    for helpline in ["Mousewheel zoom; C-p play/pause music at mouse",
-                     "Curve point bindings: B1 drag point; C-B1 curve add point; S-B1 sketch points; 1..5 add point at time; B1 drag select points",
-                     "Available in functions: nsin/ncos period=amp=1; within(a,b) bef(x) aft(x) compare to time; smoove(x) cubic smoothstep; chan(name); curvename(t) eval curve"]:
-        line = tk.Label(root, text=helpline, font="Helvetica -12 italic",
-                        anchor='w')
-        line.pack(side='top',fill='x')
-
 class Main(object):
-    def __init__(self, graph, song, curveset, subterms):
+    def __init__(self, graph, opts, song, curveset, subterms):
         self.graph = graph
         wtree = gtk.Builder()
         wtree.add_from_file(sibpath(__file__, "../light9/curvecalc/curvecalc.glade"))
@@ -125,14 +54,36 @@
         mainwin.connect("destroy", gtk.main_quit)
         wtree.connect_signals(self)
         mainwin.show_all()
-        #gobject.timeout_add(1000 // framerate, self.updateLoop)
 
+        mainwin.connect("delete-event", lambda *args: reactor.crash())
         mainwin.set_title("curvecalc - %s" % graph.label(song))
-
+        mainwin.parse_geometry("1000x1000")
+        
         self.add_subterms_for_song(song, curveset, subterms,
                                    wtree.get_object("subterms")
                                    )
 
+
+        curvesetView = Curvesetview(wtree.get_object("curves"), curveset)
+
+        # curvesetview must already exist, since this makes 'add_curve'
+        # signals for all the initial curves
+        curveset.load(basename=os.path.join(
+            showconfig.curvesDir(),
+            showconfig.songFilenameFromURI(song)),
+                      skipMusic=opts.skip_music)
+        # this is scheduled after some tk shuffling, to try to minimize
+        # the number of times we redraw the curve at startup. If tk is
+        # very slow, it's ok. You'll just get some wasted redraws.
+        curvesetView.goLive()
+        
+        self.makeStatusLines(wtree.get_object("status"))
+
+        #zc = Zoomcontrol(root)
+
+    def onSave(self, *args):
+        savekey(song, subterms, curveset)
+
     def add_subterms_for_song(self, song, curveset, subterms, master):
         for st in self.graph.objects(song, L9['subterm']):
             log.info("song %s has subterm %s", song, st)
@@ -144,6 +95,46 @@
                             self.graph.value(st, L9['expression']))
         master.show_all()
 
+    def makeStatusLines(self, master):
+        """various labels that listen for dispatcher signals"""
+        for row, (signame, textfilter) in enumerate([
+            ('input time', lambda t: "%.2fs"%t),
+            ('output levels',
+             lambda levels: textwrap.fill("; ".join(["%s:%.2f"%(n,v)
+                                                     for n,v in
+                                                     levels.items()[:5]
+                                                     if v>0]),70)),
+            ('update period', lambda t: "%.1fms"%(t*1000)),
+            ('update status', lambda x: str(x)),
+            ]):
+            key = gtk.Label("%s:" % signame)
+            value = gtk.Label("")
+            master.resize(row + 1, 2)
+            master.attach(key, 0, 1, row, row + 1)
+            master.attach(value, 1, 2, row, row + 1)
+            key.set_alignment(1, 0)
+            value.set_alignment(0, 0)
+
+            dispatcher.connect(lambda val, value=value, tf=textfilter:
+                               value.set_text(tf(val)),
+                               signame, weak=False)
+        master.show_all()
+
+
+    def onReloadSubs(self): # wants to be ctrl-r  too
+        dispatcher.send('reload all subs')
+
+    def onAddSubterm(self):
+        uri = L9['sub/%s' % newname.get()]
+        graph.add((uri, RDF.type, L9.Subterm))
+        graph.add((uri, RDFS.label, Literal(newname.get())))
+        add_one_subterm(graph, uri,
+                        curveset, subterms, ssv, None)
+        if evt.state & 4: # control key modifier
+            curveset.new_curve(newname.get())
+        newname.set('')
+
+
 def main():
     startTime = time.time()
     parser = optparse.OptionParser()
@@ -188,63 +179,15 @@
     maxtime = wavelength(musicfilename)
     dispatcher.connect(lambda: maxtime, "get max time", weak=False)
 
-    start = Main(graph, song, curveset, subterms)
-    #gtk2reactor.install()
+    start = Main(graph, opts, song, curveset, subterms)
 
+    dispatcher.send("max time", maxtime=maxtime)
+    dispatcher.send("show all")
+        
     if opts.startup_only:
         log.debug("quitting now because of --startup-only")
         return
 
-    gtk.main()
-    1/0
-    ###################
-
-
-    if 'fixed top rows':
-        zc = Zoomcontrol(root)
-        zc.pack(side='top', fill='x')
-
-    if 'panes':
-        panes = tk.PanedWindow(root, height=1)
-        panes.add('curvesetView')
-        panes.add('subterms')
-        panes.pack(side='top', fill='both', expand=True)
-
-        curvesetView = Curvesetview(panes.subwidget('curvesetView'), curveset,
-                                    height=600)
-        curvesetView.pack(fill='both', expand=True)
-
-        subtermArea = tk.Frame(panes.subwidget('subterms'), height=100)
-        subtermArea.pack(fill='both', expand=True)
-
-        subtermScroll = tk.ScrolledWindow(subtermArea)
-        subtermScroll.pack(fill='both')
-
-    if 'fixed bottom rows':
-        makeSubtermCommandRow(root, curveset, subterms, root, subtermArea,
-                              graph).pack(side='top', fill='x')
-        makeStatusLines(root)
-
-        helpBox = tk.Frame(root)
-        createHelpLines(helpBox)
-        helpBox.pack(side='top', fill='x')
-
-    setupKeyBindings(root, song, subterms, curveset)
-    setupMenubar(menubar, root, song, subterms, curveset)
-
-    # curvesetview must already exist, since this makes 'add_curve'
-    # signals for all the initial curves
-    curveset.load(basename=os.path.join(showconfig.curvesDir(),
-                                        showconfig.songFilenameFromURI(song)),
-                  skipMusic=opts.skip_music)
-    
-    dispatcher.send("max time",maxtime=maxtime)
-    dispatcher.send("show all")
-    
-    # this is scheduled after some tk shuffling, to try to minimize
-    # the number of times we redraw the curve at startup. If tk is
-    # very slow, it's ok. You'll just get some wasted redraws.
-    reactor.callLater(.1, curvesetView.goLive)
-
+    reactor.run()
 
 main()
--- a/light9/curvecalc/curve.py	Fri Jun 08 05:12:16 2012 +0000
+++ b/light9/curvecalc/curve.py	Fri Jun 08 07:38:46 2012 +0000
@@ -114,7 +114,7 @@
             self.knobButtonCallback(int(name[11:]))
 
         
-class Curveset:
+class Curveset(object):
     
     curves = None # curvename : curve
     def __init__(self, sliders=False):
@@ -172,7 +172,7 @@
             num = None
             
         dispatcher.send("add_curve", slider=num, knobEnabled=num is not None,
-                        sender=self,name=name)
+                        sender=self, name=name)
 
     def globalsdict(self):
         return self.curves.copy()
--- a/light9/curvecalc/curvecalc.glade	Fri Jun 08 05:12:16 2012 +0000
+++ b/light9/curvecalc/curvecalc.glade	Fri Jun 08 07:38:46 2012 +0000
@@ -2,6 +2,8 @@
 <interface>
   <!-- interface-requires gtk+ 3.0 -->
   <object class="GtkWindow" id="MainWindow">
+    <property name="width_request">530</property>
+    <property name="height_request">380</property>
     <property name="can_focus">False</property>
     <child>
       <object class="GtkVBox" id="vbox1">
@@ -24,6 +26,7 @@
                     <property name="can_focus">False</property>
                     <child>
                       <object class="GtkImageMenuItem" id="imagemenuitem2">
+                        <property name="label">gtk-save</property>
                         <property name="use_action_appearance">False</property>
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
@@ -32,12 +35,6 @@
                       </object>
                     </child>
                     <child>
-                      <object class="GtkSeparatorMenuItem" id="separatormenuitem1">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                      </object>
-                    </child>
-                    <child>
                       <object class="GtkImageMenuItem" id="imagemenuitem5">
                         <property name="label">gtk-quit</property>
                         <property name="use_action_appearance">False</property>
@@ -47,16 +44,6 @@
                         <property name="use_stock">True</property>
                       </object>
                     </child>
-                    <child>
-                      <object class="GtkImageMenuItem" id="imagemenuitem10">
-                        <property name="label">gtk-about</property>
-                        <property name="use_action_appearance">False</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="use_underline">True</property>
-                        <property name="use_stock">True</property>
-                      </object>
-                    </child>
                   </object>
                 </child>
               </object>
@@ -113,6 +100,57 @@
                 <property name="can_focus">False</property>
                 <property name="label" translatable="yes">_View</property>
                 <property name="use_underline">True</property>
+                <child type="submenu">
+                  <object class="GtkMenu" id="menu2">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <child>
+                      <object class="GtkMenuItem" id="menuitem8">
+                        <property name="use_action_appearance">False</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">See current time (esc)</property>
+                        <property name="use_underline">True</property>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkMenuItem" id="menuitem9">
+                        <property name="use_action_appearance">False</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">See from current time -&gt; end (S-Esc)</property>
+                        <property name="use_underline">True</property>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkMenuItem" id="menuitem10">
+                        <property name="use_action_appearance">False</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">Zoom all (C-Esc)</property>
+                        <property name="use_underline">True</property>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkMenuItem" id="menuitem11">
+                        <property name="use_action_appearance">False</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">Zoom in (wheel up)</property>
+                        <property name="use_underline">True</property>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkMenuItem" id="menuitem12">
+                        <property name="use_action_appearance">False</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">Zoom out (wheel down)</property>
+                        <property name="use_underline">True</property>
+                      </object>
+                    </child>
+                  </object>
+                </child>
               </object>
             </child>
             <child>
@@ -131,7 +169,7 @@
                         <property name="use_action_appearance">False</property>
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">Play/pause</property>
+                        <property name="label" translatable="yes">Play/pause (C-p)</property>
                         <property name="use_underline">True</property>
                       </object>
                     </child>
@@ -155,7 +193,7 @@
                         <property name="use_action_appearance">False</property>
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">menuitem6</property>
+                        <property name="label" translatable="yes">Delete (del)</property>
                         <property name="use_underline">True</property>
                       </object>
                     </child>
@@ -171,155 +209,169 @@
           </packing>
         </child>
         <child>
-          <object class="GtkVBox" id="vbox4">
+          <object class="GtkVPaned" id="paned1">
+            <property name="height_request">200</property>
             <property name="visible">True</property>
-            <property name="can_focus">False</property>
+            <property name="can_focus">True</property>
             <child>
-              <object class="GtkHBox" id="hbox9">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <child>
-                  <object class="GtkLabel" id="label15">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="label" translatable="yes">new curve named (C-N):</property>
-                  </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkEntry" id="entry4">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="invisible_char">●</property>
-                    <property name="primary_icon_activatable">False</property>
-                    <property name="secondary_icon_activatable">False</property>
-                  </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkScrolledWindow" id="scrolledwindow1">
+              <object class="GtkExpander" id="expander2">
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
-                <property name="hscrollbar_policy">never</property>
+                <property name="expanded">True</property>
                 <child>
-                  <object class="GtkVBox" id="vbox5">
+                  <object class="GtkVBox" id="vbox4">
+                    <property name="height_request">100</property>
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <child>
-                      <object class="GtkHandleBox" id="handlebox1">
+                      <object class="GtkHBox" id="hbox9">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
                         <child>
-                          <object class="GtkHBox" id="hbox8">
+                          <object class="GtkLabel" id="label15">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="label" translatable="yes">new curve named (C-N):</property>
+                          </object>
+                          <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkEntry" id="entry4">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="invisible_char">●</property>
+                            <property name="invisible_char_set">True</property>
+                            <property name="primary_icon_activatable">False</property>
+                            <property name="secondary_icon_activatable">False</property>
+                          </object>
+                          <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkScrolledWindow" id="scrolledwindow1">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="hscrollbar_policy">never</property>
+                        <child>
+                          <object class="GtkViewport" id="viewport2">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
                             <child>
-                              <object class="GtkFrame" id="frame2">
+                              <object class="GtkVBox" id="curves">
                                 <property name="visible">True</property>
                                 <property name="can_focus">False</property>
-                                <property name="border_width">5</property>
-                                <property name="label_xalign">0</property>
-                                <property name="label_yalign">0</property>
-                                <property name="shadow_type">out</property>
+                                <child>
+                                  <placeholder/>
+                                </child>
                                 <child>
-                                  <object class="GtkVBox" id="vbox6">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">False</property>
-                                    <child>
-                                      <object class="GtkLabel" id="label16">
-                                        <property name="visible">True</property>
-                                        <property name="can_focus">False</property>
-                                        <property name="label" translatable="yes">curve 'music'</property>
-                                      </object>
-                                      <packing>
-                                        <property name="expand">False</property>
-                                        <property name="fill">False</property>
-                                        <property name="position">0</property>
-                                      </packing>
-                                    </child>
-                                    <child>
-                                      <object class="GtkHBox" id="hbox10">
-                                        <property name="visible">True</property>
-                                        <property name="can_focus">False</property>
-                                        <child>
-                                          <object class="GtkCheckButton" id="checkbutton3">
-                                            <property name="label" translatable="yes">C</property>
-                                            <property name="use_action_appearance">False</property>
-                                            <property name="visible">True</property>
-                                            <property name="can_focus">True</property>
-                                            <property name="receives_default">False</property>
-                                            <property name="use_action_appearance">False</property>
-                                            <property name="xalign">0.5</property>
-                                            <property name="draw_indicator">True</property>
-                                          </object>
-                                          <packing>
-                                            <property name="expand">True</property>
-                                            <property name="fill">True</property>
-                                            <property name="position">0</property>
-                                          </packing>
-                                        </child>
-                                        <child>
-                                          <object class="GtkCheckButton" id="checkbutton4">
-                                            <property name="label" translatable="yes">M</property>
-                                            <property name="use_action_appearance">False</property>
-                                            <property name="visible">True</property>
-                                            <property name="can_focus">True</property>
-                                            <property name="receives_default">False</property>
-                                            <property name="use_action_appearance">False</property>
-                                            <property name="xalign">0.5</property>
-                                            <property name="draw_indicator">True</property>
-                                          </object>
-                                          <packing>
-                                            <property name="expand">True</property>
-                                            <property name="fill">True</property>
-                                            <property name="position">1</property>
-                                          </packing>
-                                        </child>
-                                      </object>
-                                      <packing>
-                                        <property name="expand">False</property>
-                                        <property name="fill">False</property>
-                                        <property name="position">1</property>
-                                      </packing>
-                                    </child>
-                                  </object>
+                                  <placeholder/>
                                 </child>
-                                <child type="label_item">
+                                <child>
                                   <placeholder/>
                                 </child>
                               </object>
-                              <packing>
-                                <property name="expand">False</property>
-                                <property name="fill">False</property>
-                                <property name="position">0</property>
-                              </packing>
                             </child>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                </child>
+                <child type="label">
+                  <object class="GtkLabel" id="label10">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Curves</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="resize">False</property>
+                <property name="shrink">True</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkExpander" id="expander1">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="expanded">True</property>
+                <child>
+                  <object class="GtkVBox" id="box1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <child>
+                      <object class="GtkScrolledWindow" id="scrolledwindow2">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="vscrollbar_policy">always</property>
+                        <child>
+                          <object class="GtkViewport" id="viewport1">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="vscroll_policy">natural</property>
+                            <property name="shadow_type">none</property>
                             <child>
-                              <object class="GtkImage" id="image2">
+                              <object class="GtkTable" id="subterms">
+                                <property name="height_request">90</property>
                                 <property name="visible">True</property>
                                 <property name="can_focus">False</property>
-                                <property name="pixbuf">samplecurve.png</property>
+                                <property name="n_columns">2</property>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                                <child>
+                                  <placeholder/>
+                                </child>
                               </object>
-                              <packing>
-                                <property name="expand">True</property>
-                                <property name="fill">True</property>
-                                <property name="position">1</property>
-                              </packing>
                             </child>
                           </object>
                         </child>
@@ -331,18 +383,71 @@
                       </packing>
                     </child>
                     <child>
-                      <placeholder/>
+                      <object class="GtkHBox" id="box2">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <child>
+                          <object class="GtkButton" id="button1">
+                            <property name="label" translatable="yes">Reload subs (C-r)</property>
+                            <property name="use_action_appearance">False</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">True</property>
+                            <property name="use_action_appearance">False</property>
+                            <property name="image">image2</property>
+                            <signal name="clicked" handler="onReloadSubs" swapped="no"/>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label2">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="label" translatable="yes">new subterm named (C-Enter for curve too, C-n for focus):</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkEntry" id="entry1">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="invisible_char">●</property>
+                            <property name="invisible_char_set">True</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">2</property>
+                          </packing>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">1</property>
+                      </packing>
                     </child>
-                    <child>
-                      <placeholder/>
-                    </child>
+                  </object>
+                </child>
+                <child type="label">
+                  <object class="GtkLabel" id="subtermsLabel">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Subterms</property>
                   </object>
                 </child>
               </object>
               <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
+                <property name="resize">True</property>
+                <property name="shrink">True</property>
               </packing>
             </child>
           </object>
@@ -353,194 +458,47 @@
           </packing>
         </child>
         <child>
-          <object class="GtkExpander" id="expander1">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="expanded">True</property>
-            <child>
-              <object class="GtkScrolledWindow" id="scrolledwindow2">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="vscrollbar_policy">always</property>
-                <child>
-                  <object class="GtkViewport" id="viewport1">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="shadow_type">none</property>
-                    <child>
-                      <object class="GtkTable" id="subterms">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="n_columns">2</property>
-                        <child>
-                          <placeholder/>
-                        </child>
-                        <child>
-                          <placeholder/>
-                        </child>
-                      </object>
-                    </child>
-                  </object>
-                </child>
-              </object>
-            </child>
-            <child type="label">
-              <object class="GtkLabel" id="subtermsLabel">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="label" translatable="yes">Subterms</property>
-              </object>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">2</property>
-          </packing>
-        </child>
-        <child>
           <object class="GtkHBox" id="hbox1">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
             <child>
-              <object class="GtkVBox" id="status">
+              <object class="GtkFrame" id="frame2">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
+                <property name="label_xalign">0</property>
+                <property name="shadow_type">none</property>
                 <child>
-                  <object class="GtkHBox" id="hbox2">
+                  <object class="GtkTable" id="status">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
+                    <property name="n_columns">2</property>
                     <child>
-                      <object class="GtkLabel" id="label1">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">input time:</property>
-                      </object>
-                      <packing>
-                        <property name="expand">True</property>
-                        <property name="fill">True</property>
-                        <property name="position">0</property>
-                      </packing>
+                      <placeholder/>
                     </child>
                     <child>
-                      <object class="GtkLabel" id="label2">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                      </object>
-                      <packing>
-                        <property name="expand">True</property>
-                        <property name="fill">True</property>
-                        <property name="position">1</property>
-                      </packing>
+                      <placeholder/>
                     </child>
-                  </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkHBox" id="hbox3">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
                     <child>
-                      <object class="GtkLabel" id="label3">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">output levels:</property>
-                      </object>
-                      <packing>
-                        <property name="expand">True</property>
-                        <property name="fill">True</property>
-                        <property name="position">0</property>
-                      </packing>
+                      <placeholder/>
                     </child>
                     <child>
-                      <object class="GtkLabel" id="label4">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                      </object>
-                      <packing>
-                        <property name="expand">True</property>
-                        <property name="fill">True</property>
-                        <property name="position">1</property>
-                      </packing>
+                      <placeholder/>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                    <child>
+                      <placeholder/>
                     </child>
                   </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
                 </child>
-                <child>
-                  <object class="GtkHBox" id="hbox4">
+                <child type="label">
+                  <object class="GtkLabel" id="label1">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <child>
-                      <object class="GtkLabel" id="label5">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">update period:</property>
-                      </object>
-                      <packing>
-                        <property name="expand">True</property>
-                        <property name="fill">True</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="label6">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                      </object>
-                      <packing>
-                        <property name="expand">True</property>
-                        <property name="fill">True</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
+                    <property name="label" translatable="yes">Status</property>
+                    <property name="use_markup">True</property>
                   </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">2</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkHBox" id="hbox12">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <child>
-                      <object class="GtkLabel" id="label7">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">update status:</property>
-                      </object>
-                      <packing>
-                        <property name="expand">True</property>
-                        <property name="fill">True</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="label8">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                      </object>
-                      <packing>
-                        <property name="expand">True</property>
-                        <property name="fill">True</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">3</property>
-                  </packing>
                 </child>
               </object>
               <packing>
@@ -605,6 +563,20 @@
             <property name="expand">False</property>
             <property name="fill">False</property>
             <property name="padding">5</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkTextView" id="textview1">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="editable">False</property>
+            <property name="wrap_mode">word</property>
+            <property name="buffer">help</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
             <property name="position">3</property>
           </packing>
         </child>
@@ -612,6 +584,141 @@
     </child>
   </object>
   <object class="GtkAccelGroup" id="accelgroup1"/>
+  <object class="GtkTextBuffer" id="help">
+    <property name="text">Mousewheel zoom; C-p play/pause music at mouse
+Curve point bindings: B1 drag point; C-B1 curve add point; S-B1 sketch points; 1..5 add point at time; B1 drag select points
+Available in functions: nsin/ncos period=amp=1; within(a,b) bef(x) aft(x) compare to time; smoove(x) cubic smoothstep; chan(name); curvename(t) eval curve</property>
+  </object>
+  <object class="GtkImage" id="image2">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="stock">gtk-refresh</property>
+  </object>
+  <object class="GtkOffscreenWindow" id="offscreenwindow1">
+    <property name="can_focus">False</property>
+    <child>
+      <object class="GtkVBox" id="vbox3">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <child>
+          <object class="GtkHandleBox" id="handlebox2">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <child>
+              <object class="GtkHBox" id="hbox5">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <child>
+                  <object class="GtkFrame" id="frame1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="border_width">5</property>
+                    <property name="label_xalign">0</property>
+                    <property name="label_yalign">0</property>
+                    <property name="shadow_type">out</property>
+                    <child>
+                      <object class="GtkVBox" id="vbox8">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <child>
+                          <object class="GtkLabel" id="label9">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="label" translatable="yes">curve 'music'</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkHBox" id="hbox6">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <child>
+                              <object class="GtkCheckButton" id="checkbutton1">
+                                <property name="label" translatable="yes">C</property>
+                                <property name="use_action_appearance">False</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="use_action_appearance">False</property>
+                                <property name="xalign">0</property>
+                                <property name="draw_indicator">True</property>
+                              </object>
+                              <packing>
+                                <property name="expand">True</property>
+                                <property name="fill">True</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkCheckButton" id="checkbutton2">
+                                <property name="label" translatable="yes">M</property>
+                                <property name="use_action_appearance">False</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="use_action_appearance">False</property>
+                                <property name="xalign">0</property>
+                                <property name="draw_indicator">True</property>
+                              </object>
+                              <packing>
+                                <property name="expand">True</property>
+                                <property name="fill">True</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                    <child type="label_item">
+                      <placeholder/>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkImage" id="image4">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="stock">gtk-media-forward</property>
+                  </object>
+                  <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+      </object>
+    </child>
+  </object>
   <object class="GtkTextBuffer" id="textbuffer1">
     <property name="text" translatable="yes">song01(t)</property>
   </object>
--- a/light9/curvecalc/curveview.py	Fri Jun 08 05:12:16 2012 +0000
+++ b/light9/curvecalc/curveview.py	Fri Jun 08 07:38:46 2012 +0000
@@ -1,6 +1,6 @@
 from __future__ import division
 import math, time, logging
-import Tix as tk
+import gtk, goocanvas
 import louie as dispatcher
 from light9.curvecalc.zoomcontrol import RegionZoom
 from light9.curvecalc import cursors
@@ -67,19 +67,22 @@
             
         self.curveview.update_curve()
 
-class Curveview(tk.Canvas):
-    def __init__(self, master, curve, knobEnabled=False, isMusic=False, **kw):
+class Curveview(object):
+    """
+    graphical curve widget only. Please pack .widget
+    """
+    def __init__(self, curve, knobEnabled=False, isMusic=False, **kw):
         """knobEnabled=True highlights the previous key and ties it to a
         hardware knob"""
+        self.widget = goocanvas.Canvas()
+        self.root = self.widget.get_root_item()
+
         self.redrawsEnabled = False
         self.curve = curve
         self.knobEnabled = knobEnabled
         self._isMusic = isMusic
         self._time = 0
         self.last_mouse_world = None
-        tk.Canvas.__init__(self,master,width=10,height=10,
-                           relief='sunken',bd=1,
-                           closeenough=5,takefocus=1, **kw)
         self.selected_points=[] # idx of points being dragged
         # self.bind("<Enter>",self.focus)
         dispatcher.connect(self.input_time, "input time")
@@ -92,64 +95,70 @@
         if self.knobEnabled:
             dispatcher.connect(self.knob_in, "knob in")
             dispatcher.connect(self.slider_in, "set key")
-        self.bind("<Configure>",self.update_curve)
-        for x in range(1, 6):
-            def add_kb_marker_point(evt, x=x):
-                self.add_point((self.current_time(), (x - 1) / 4.0))
+        print "setup alloc", self.__dict__
+        self.widget.connect("size-allocate", self.update_curve)
+        if 0:
 
-            self.bind("<Key-%s>" % x, add_kb_marker_point)
+            for x in range(1, 6):
+                def add_kb_marker_point(evt, x=x):
+                    self.add_point((self.current_time(), (x - 1) / 4.0))
+
+                self.bind("<Key-%s>" % x, add_kb_marker_point)
 
 
-        for butnum,factor in (5, 1.5),(4, 1/1.5):
-            def onMouseWheel(ev,factor=factor):
-                dispatcher.send("zoom about mouse",
-                                t=self.world_from_screen(ev.x,0)[0],
-                                factor=factor)
-                # this is supposed to make the canvases redraw more
-                # visibly, so we don't waste line redraws that never
-                # get seen. I'm not sure if it works.
-                self.update()
-            self.bind("<ButtonPress-%s>" % butnum, onMouseWheel)
-        self.bind("<Key-Escape>", lambda ev:
-                  dispatcher.send("see time",
-                                  t=self.current_time()))
-        self.bind("<Shift-Escape>", lambda ev:
-                  dispatcher.send("see time until end",
-                                  t=self.current_time()))
-        self.bind("<Control-Escape>", lambda ev: dispatcher.send("show all"))
-        self.bind("<Control-p>", lambda ev:
-                  dispatcher.send("music seek",
-                                  t=self.world_from_screen(ev.x,0)[0]))
+            for butnum,factor in (5, 1.5),(4, 1/1.5):
+                def onMouseWheel(ev,factor=factor):
+                    dispatcher.send("zoom about mouse",
+                                    t=self.world_from_screen(ev.x,0)[0],
+                                    factor=factor)
+                    # this is supposed to make the canvases redraw more
+                    # visibly, so we don't waste line redraws that never
+                    # get seen. I'm not sure if it works.
+                    self.update()
+                self.bind("<ButtonPress-%s>" % butnum, onMouseWheel)
+            self.bind("<Key-Escape>", lambda ev:
+                      dispatcher.send("see time",
+                                      t=self.current_time()))
+            self.bind("<Shift-Escape>", lambda ev:
+                      dispatcher.send("see time until end",
+                                      t=self.current_time()))
+            self.bind("<Control-Escape>", lambda ev: dispatcher.send("show all"))
+            self.bind("<Control-p>", lambda ev:
+                      dispatcher.send("music seek",
+                                      t=self.world_from_screen(ev.x,0)[0]))
 
-        self.bind("<Motion>",
-                  self.dotmotion, add=True)
-        self.bind("<ButtonRelease-1>",
-                  self.dotrelease, add=True)
+            self.bind("<Motion>",
+                      self.dotmotion, add=True)
+            self.bind("<ButtonRelease-1>",
+                      self.dotrelease, add=True)
 
 
         # this binds on c-a-b1, etc
-        self.regionzoom = RegionZoom(self, self.world_from_screen,
-                                     self.screen_from_world)
+        if 0:
+            self.regionzoom = RegionZoom(self, self.world_from_screen,
+                                         self.screen_from_world)
 
         self.sketch = None # an in-progress sketch
-        self.bind("<Shift-ButtonPress-1>", self.sketch_press)
-        self.bind("<Shift-B1-Motion>", self.sketch_motion)
-        self.bind("<Shift-ButtonRelease-1>", self.sketch_release)
+        if 0:
+            self.bind("<Shift-ButtonPress-1>", self.sketch_press)
+            self.bind("<Shift-B1-Motion>", self.sketch_motion)
+            self.bind("<Shift-ButtonRelease-1>", self.sketch_release)
 
 
         self.dragging_dots = False
         self.selecting = False
-        self.bind("<ButtonPress-1>",#"<Alt-Key>",
-                  self.select_press, add=True)
-        self.bind("<Motion>", self.select_motion, add=True)
-        self.bind("<ButtonRelease-1>", #"<Alt-KeyRelease>",
-                  self.select_release, add=True)
+        if 0:
+            self.bind("<ButtonPress-1>",#"<Alt-Key>",
+                      self.select_press, add=True)
+            self.bind("<Motion>", self.select_motion, add=True)
+            self.bind("<ButtonRelease-1>", #"<Alt-KeyRelease>",
+                      self.select_release, add=True)
 
-        self.bind("<ButtonPress-1>", self.check_deselect, add=True)
+            self.bind("<ButtonPress-1>", self.check_deselect, add=True)
 
-        self.bind("<Key-m>", lambda *args: self.curve.toggleMute())
-        self.bind("<Key-c>", lambda *args: dispatcher.send('toggle collapse',
-                                                           sender=self.curve))
+            self.bind("<Key-m>", lambda *args: self.curve.toggleMute())
+            self.bind("<Key-c>", lambda *args: dispatcher.send('toggle collapse',
+                                                               sender=self.curve))
 
     def goLive(self):
         """this is for startup performance only, since the curves were
@@ -241,13 +250,13 @@
 
     def screen_from_world(self,p):
         start,end = self.zoom
-        ht = self.height
-        return (p[0]-start)/(end-start)*self.width, (ht-5)-p[1]*(ht-10)
+        ht = self.size.height
+        return (p[0]-start)/(end-start)*self.size.width, (ht-5)-p[1]*(ht-10)
 
     def world_from_screen(self,x,y):
         start,end = self.zoom
-        ht = self.height
-        return x/self.width*(end-start)+start, ((ht-5)-y)/(ht-10)
+        ht = self.size.height
+        return x/self.size.width*(end-start)+start, ((ht-5)-y)/(ht-10)
     
     def input_time(self, val, forceUpdate=False):
         # i tried various things to make this not update like crazy,
@@ -255,7 +264,7 @@
         # scared that things were getting built in a funny order.        
         #if self._time == val:
         #    return
-        
+        return
         t=val
         pts = self.screen_from_world((val,0))+self.screen_from_world((val,1))
         self.delete('timecursor')
@@ -273,29 +282,33 @@
                                  tags=('knob',))
                 dispatcher.send("knob out", value=prevKey[1], curve=self.curve)
         
-    def update_curve(self,*args):
-        if not self.redrawsEnabled:
+    def update_curve(self, _widget=None, _rect=None):
+        print "update curve on", self, id(self), self.__dict__
+        if not getattr(self, 'redrawsEnabled', False):
             return
-        self.width, self.height = self.winfo_width(), self.winfo_height()
+        self.size = self.widget.get_allocation()
 
-        self.zoom = dispatcher.send("zoom area")[0][1]
+        self.zoom = 0, 3#dispatcher.send("zoom area")[0][1]
         cp = self.curve.points
 
         visible_x = (self.world_from_screen(0,0)[0],
-                     self.world_from_screen(self.width, 0)[0])
+                     self.world_from_screen(self.size.width, 0)[0])
 
         visible_idxs = self.curve.indices_between(visible_x[0], visible_x[1],
                                                   beyond=1)
         visible_points = [cp[i] for i in visible_idxs]
-        
-        self.delete('curve')
+
+        if getattr(self, 'curveGroup', None):
+            self.curveGroup.remove()
+        self.curveGroup = goocanvas.Group(parent=self.root)
 
-        if self.curve.muted:
-            self['bg'] = 'grey20'
-        else:
-            self['bg'] = 'black'
+        if 0:
+            if self.curve.muted:
+                self['bg'] = 'grey20'
+            else:
+                self['bg'] = 'black'
 
-        if self.height < 40:
+        if self.size.height < .40:
             self._draw_gradient()
         else:
             self._draw_markers(visible_x)
@@ -312,11 +325,13 @@
         return self._isMusic
 
     def _draw_gradient(self):
+        print "no grad"
+        return
         t1 = time.time()
         gradient_res = 6 if self.is_music() else 3
         startX = startColor = None
         rects = 0
-        for x in range(0, self.width, gradient_res):
+        for x in range(0, self.size.width, gradient_res):
             wx = self.world_from_screen(x,0)[0]
             mag = self.curve.eval(wx, allow_muting=False)
             if self.curve.muted:
@@ -334,7 +349,7 @@
                 startColor = color
 
         if startColor is not None:
-            self._draw_gradient_slice(startX, self.width, startColor)
+            self._draw_gradient_slice(startX, self.size.width, startColor)
             rects += 1
         log.debug("redraw %s rects in %.02f ms", rects, 1000 * (time.time()-t1))
 
@@ -343,6 +358,7 @@
                               fill=color, width=0, tags='curve')        
 
     def _draw_markers(self,visible_x):
+        return
         mark = self._draw_one_marker
 
         mark(0,"0")
@@ -360,8 +376,8 @@
         
     def _draw_one_marker(self,t,label):
         x = self.screen_from_world((t,0))[0]
-        ht = self.height
-        if not 0 <= x < self.winfo_width():
+        ht = self.size.height
+        if not 0 <= x < self.size.width:
             return
         x = max(5, x) # cheat left-edge stuff onscreen
         self.create_line(x, ht,
@@ -380,26 +396,32 @@
             step = int(len(visible_points)/800)
             linewidth=1
         for p in visible_points[::step]:
-            linepts.extend(self.screen_from_world(p))
+            linepts.append(self.screen_from_world(p))
         if len(linepts)<4:
             return
         if self.curve.muted:
             fill = 'grey34'
         else:
             fill = 'white'
-        kwargs = dict(width=linewidth, tags='curve', fill=fill)
-        line = self.create_line(*linepts, **kwargs)
 
+        goocanvas.Polyline(parent=self.curveGroup,
+                           points=goocanvas.Points(linepts),
+                           width=linewidth,
+                           stroke_color=fill,
+                           )
+            
         # canvas doesnt have keyboard focus, so i can't easily change the
         # cursor when ctrl is pressed
         #        def curs(ev):
         #            print ev.state
         #        self.bind("<KeyPress>",curs)
         #        self.bind("<KeyRelease-Control_L>",lambda ev: curs(0))
-        self.tag_bind(line,"<Control-ButtonPress-1>",self.new_point_at_mouse)
+        if 0:
+            self.tag_bind(line,"<Control-ButtonPress-1>",self.new_point_at_mouse)
 
 
     def _draw_handle_points(self,visible_idxs,visible_points):
+        return
         for i,p in zip(visible_idxs,visible_points):
             rad=3
             worldp = p
@@ -539,61 +561,69 @@
         self.last_mouse_world = None
         self.dragging_dots = False
 
-class CurveRow(tk.Frame):
+class CurveRow(object):
     """
     one of the repeating curve rows (including widgets on the left)
-    """
-    def __init__(self, master, name, curve, slider, knobEnabled):
-        tk.Frame.__init__(self, master, relief='raised', bd=1)
 
-        self.collapsed = tk.IntVar()
-        self.muted = tk.IntVar()
+    please pack self.box
+    """
+    def __init__(self, name, curve, slider, knobEnabled):
 
-        labelFont = "arial 8"
+        self.box = gtk.HandleBox()
 
-        leftside = tk.Frame(self)
-        leftside.pack(side='left')
+        cols = gtk.HBox()
+        self.box.add(cols)
+        
+        controls = gtk.Frame()
+        controls.set_size_request(115, -1)
+        controls.set_shadow_type(gtk.SHADOW_OUT)
+        cols.pack_start(controls, expand=False)
+        self.setupControls(controls, name, curve, slider)
 
-        self.curveView = Curveview(self, curve, knobEnabled=knobEnabled,
+        self.curveView = Curveview(curve, knobEnabled=knobEnabled,
                                    isMusic=name in ['music', 'smooth_music'])
-        self.curveView.pack(side='left', fill='both', expand=True)
-        self.curveView.config(height=100)
-
+        cols.pack_start(self.curveView.widget, expand=True)
+        
+    def setupControls(self, controls, name, curve, slider):
+        box = gtk.VBox()
+        controls.add(box)
+        
         txt = "curve '%s'" % name
         if len(name) > 7:
             txt = name
-        curve_name_label = tk.Label(leftside, text=txt, font=labelFont,width=15)
-        curve_name_label.pack(side='top')
+        curve_name_label = gtk.Label(txt)
+        box.pack_start(curve_name_label)
+
 
-        bools = tk.Frame(leftside)
-        bools.pack(side='top')
-        collapsed_cb = tk.Checkbutton(bools, text="C",
-                                      font=labelFont, variable=self.collapsed)
-        collapsed_cb.pack(side='left')
-        self.collapsed.trace('w', self.update_ui_to_collapsed_state)
+#        self.collapsed = tk.IntVar()
+#        self.muted = tk.IntVar()
+
+        bools = gtk.HBox()
+        box.pack_start(bools)
+        collapsed_cb = gtk.CheckButton("C")
+        bools.pack_start(collapsed_cb)
+        #self.collapsed.trace('w', self.update_ui_to_collapsed_state)
         dispatcher.connect(self.toggleCollapsed, "toggle collapse",
                            sender=curve)
 
-        self.default_bg = leftside['bg']
-        muted_cb = tk.Checkbutton(bools, text="M", font=labelFont,
-                                  variable=self.muted)
-        muted_cb.pack(side='left')
-        self.muted.trace('w', self.sync_mute_to_curve)
+        muted_cb = gtk.CheckButton("M")
+        
+        bools.pack_start(muted_cb)
+        #self.muted.trace('w', self.sync_mute_to_curve)
         dispatcher.connect(self.mute_changed, 'mute changed', sender=curve)
 
         self.sliderLabel = None
         if slider is not None:
             # slider should have a checkbutton, defaults to off for
             # music tracks
-            self.sliderLabel = tk.Label(leftside, text="Slider %s" % slider,
-                                        fg='#800000', font=labelFont)
-            self.sliderLabel.pack(side='top')
+            self.sliderLabel = gtk.Label("Slider %s" % slider)
+            box.pack_start(self.sliderLabel)
 
         # widgets that need recoloring when we tint the row:
-        self.widgets = [leftside, collapsed_cb, muted_cb,
-                        curve_name_label, self]
-        if self.sliderLabel:
-            self.widgets.append(self.sliderLabel)
+        #self.widgets = [leftside, collapsed_cb, muted_cb,
+        #                curve_name_label, self]
+        #if self.sliderLabel:
+        #    self.widgets.append(self.sliderLabel)
 
     def toggleCollapsed(self):
         self.collapsed.set(not self.collapsed.get())
@@ -633,18 +663,20 @@
         self.update_mute_look()
 
 
-class Curvesetview(tk.ScrolledWindow):
-    def __init__(self, master, curveset, **kw):
+class Curvesetview(object):
+    """
+    
+    """
+    def __init__(self, curvesVBox, curveset):
+        self.curvesVBox = curvesVBox
         self.curveset = curveset
         self.allCurveRows = set()
-        tk.ScrolledWindow.__init__(self,master,**kw)
+
+        dispatcher.connect(self.add_curve, "add_curve", sender=self.curveset)
         
-        f = tk.Frame(self.window,relief='raised',bd=1)
-        f.pack(side='top',fill='x')
-        tk.Label(f, text="new curve named: (C-N)").pack(side='left')
-        
-        self.newcurvename = tk.StringVar()
-        
+        self.newcurvename = gtk.EntryBuffer("", 0)
+        return
+
         entry = tk.Entry(f, textvariable=self.newcurvename)
         entry.pack(side='left', fill='x',exp=1)        
         entry.bind("<Key-Return>", self.new_curve)
@@ -652,7 +684,7 @@
         def focus_entry():
             entry.focus()
         
-        dispatcher.connect(self.add_curve, "add_curve", sender=self.curveset)
+        
         dispatcher.connect(focus_entry, "focus new curve", weak=False)
 
     def new_curve(self, event):
@@ -661,11 +693,13 @@
         
     def add_curve(self, name, slider=None, knobEnabled=False):
         curve = self.curveset.curves[name]
-        f = CurveRow(self.window, name, curve, slider, knobEnabled)
-        f.pack(side='top', fill='both')
+        f = CurveRow(name, curve, slider, knobEnabled)
+        self.curvesVBox.pack_end(f.box)
+        f.box.show_all()
         self.allCurveRows.add(f)
         f.curveView.goLive()
 
+
     def goLive(self):
         """for startup performance, none of the curves redraw
         themselves until this is called once (and then they're normal)"""
--- a/light9/curvecalc/musicaccess.py	Fri Jun 08 05:12:16 2012 +0000
+++ b/light9/curvecalc/musicaccess.py	Fri Jun 08 07:38:46 2012 +0000
@@ -63,7 +63,7 @@
         return done
 
     def _bodyReceived(self, data):
-        dispatcher.send("input time",val=data['t'])
+        dispatcher.send("input time", val=data['t'])
         return data['t'] # pass along to the real receiver
     
     def seekplay_or_pause(self,t):
--- a/light9/curvecalc/output.py	Fri Jun 08 05:12:16 2012 +0000
+++ b/light9/curvecalc/output.py	Fri Jun 08 07:38:46 2012 +0000
@@ -22,16 +22,15 @@
     def updateerr(self,e):
 
         print e.getTraceback()
-        dispatcher.send("update status",val=e.getErrorMessage())
+        dispatcher.send("update status", val=e.getErrorMessage())
         if self.later and not self.later.cancelled and not self.later.called:
             self.later.cancel()
-        self.later = reactor.callLater(1,self.update)
+        self.later = reactor.callLater(1, self.update)
         
     def update2(self,t):
         # spot alsa soundcard offset is always 0, we get times about a
         # second ahead of what's really getting played
         #t = t - .7
-        
         dispatcher.send("update status",
                         val="ok: receiving time from music player")
         if self.later and not self.later.cancelled and not self.later.called:
--- a/light9/curvecalc/subtermview.py	Fri Jun 08 05:12:16 2012 +0000
+++ b/light9/curvecalc/subtermview.py	Fri Jun 08 07:38:46 2012 +0000
@@ -68,43 +68,9 @@
     stv = Subtermview(graph, term)
     y = master.get_property('n-rows')
     master.resize(y + 1, columns=2)
-    master.attach(stv.label, 0, 1, y, y + 1, xoptions=0)
-    master.attach(stv.exprView, 1, 2, y, y + 1)
+    master.attach(stv.label, 0, 1, y, y + 1, xoptions=0, yoptions=0)
+    master.attach(stv.exprView, 1, 2, y, y + 1, yoptions=0)
 
     return term
 
 
-
-def makeSubtermCommandRow(master, curveset, subterms, root, ssv, graph):
-    """
-    the row that starts with 'reload subs' button
-    """
-    f=tk.Frame(master,relief='raised',bd=1)
-    newname = tk.StringVar()
-
-    def add_cmd(evt):
-        uri = L9['sub/%s' % newname.get()]
-        graph.add((uri, RDF.type, L9.Subterm))
-        graph.add((uri, RDFS.label, Literal(newname.get())))
-        add_one_subterm(graph, uri,
-                        curveset, subterms, ssv, None)
-        if evt.state & 4: # control key modifier
-            curveset.new_curve(newname.get())
-        newname.set('')
-
-    def reload_subs():
-        dispatcher.send('reload all subs')
-
-    tk.Button(f, text="reload subs (C-r)", 
-        command=reload_subs).pack(side='left')
-    tk.Label(f, text="new subterm named (C-Enter for curve too, C-n for focus):").pack(side='left')
-    entry = tk.Entry(f, textvariable=newname)
-    entry.pack(side='left', fill='x', exp=1)
-    entry.bind("<Key-Return>", add_cmd)
-
-    def focus_entry():
-        entry.focus()
-        
-    dispatcher.connect(focus_entry, "focus new subterm", weak=False)
-
-    return f