changeset 1056:547d65ea9902

port curvecalc to gtk3. mostly worked, but there are severe bugs with redraws Ignore-this: 2a9ba18d1c180831446257054e5d7e8a
author Drew Perttula <drewp@bigasterisk.com>
date Sun, 01 Jun 2014 20:35:38 +0000
parents 6ce00faec207
children 2448ebc38a6f
files bin/curvecalc lib/ipython_view.py light9/curvecalc/curvecalc.glade light9/curvecalc/curveview.py light9/curvecalc/subtermview.py light9/curvecalc/zoomcontrol.py light9/editchoicegtk.py light9/gtkpyconsole.py makefile
diffstat 9 files changed, 378 insertions(+), 315 deletions(-) [+]
line wrap: on
line diff
--- a/bin/curvecalc	Sun Jun 01 10:39:17 2014 +0000
+++ b/bin/curvecalc	Sun Jun 01 20:35:38 2014 +0000
@@ -13,11 +13,16 @@
 
 import sys
 sys.path.append('/usr/lib/python2.7/dist-packages') # For gtk
-from twisted.internet import gtk2reactor
-gtk2reactor.install()
+from twisted.internet import gtk3reactor
+gtk3reactor.install()
 from twisted.internet import reactor
 
-import time, textwrap, os, optparse, gtk, linecache, signal, traceback, json
+import time, textwrap, os, optparse, linecache, signal, traceback, json
+import gi
+from gi.repository import Gtk
+from gi.repository import GObject
+from gi.repository import Gdk
+
 from urlparse import parse_qsl
 import louie as dispatcher 
 from rdflib import URIRef, Literal, RDF, RDFS
@@ -37,7 +42,7 @@
 from light9.gtkpyconsole import togglePyConsole
 from light9.rdfdb.syncedgraph import SyncedGraph
 from light9.rdfdb.patch import Patch
-from light9.editchoicegtk import EditChoice
+from light9.editchoicegtk import EditChoice, Local
 from light9.observable import Observable
 
 class SubtermExists(ValueError):
@@ -50,14 +55,14 @@
         self.lastSeenInputTime = 0
         self.currentSubterms = [] # Subterm objects that are synced to the graph
 
-        wtree = self.wtree = gtk.Builder()
+        wtree = self.wtree = Gtk.Builder()
         wtree.add_from_file("light9/curvecalc/curvecalc.glade")
         mainwin = wtree.get_object("MainWindow")
         
         mainwin.connect("destroy", self.onQuit)
         wtree.connect_signals(self)
-        gtk.rc_parse("theme/marble-ice/gtk-2.0/gtkrc")
-        gtk.rc_parse_string("""style "default" {font_name = "sans 9"}""")
+        Gtk.rc_parse("theme/marble-ice/gtk-2.0/gtkrc")
+        Gtk.rc_parse_string("""style "default" {font_name = "sans 9"}""")
         if self.opts.reload:
             self.refreshTheme()
         mainwin.show_all()
@@ -82,6 +87,8 @@
         graph.addHandler(setSong)
         # next here, watch songChoice and patch the graph
         def songToGraph(newSong):
+            if newSong is Local:
+                raise NotImplementedError('what do i patch')
             graph.patchObject(context=session, subject=session,
                               predicate=L9['currentSong'], newObject=newSong)
         songChoice.subscribe(songToGraph)
@@ -100,14 +107,13 @@
                 
         self.current_player_song = current_player_song
         dispatcher.connect(current_player_song, "current_player_song")
-        
+
         ec = EditChoice(graph, songChoice, label="Editing song:")
         wtree.get_object("currentSongEditChoice").add(ec)
         ec.show()
         
         wtree.get_object("subterms").connect("add", self.onSubtermChildAdded)
         
-
         self.refreshCurveView()       
         
         self.makeStatusLines(wtree.get_object("status"))
@@ -119,15 +125,15 @@
 
     def setupNewSubZone(self):
         self.wtree.get_object("newSubZone").drag_dest_set(
-            flags=gtk.DEST_DEFAULT_ALL,
-            targets=[('text/uri-list', 0, 0)],
-            actions=gtk.gdk.ACTION_COPY)
+            flags=Gtk.DestDefaults.ALL,
+            targets=[Gtk.TargetEntry('text/uri-list', 0, 0)],
+            actions=Gdk.DragAction.COPY)
         
     def acceptDragsOnCurveViews(self):
         w = self.wtree.get_object("curves")
-        w.drag_dest_set(flags=gtk.DEST_DEFAULT_ALL,
-                        targets=[('text/uri-list', 0, 0)],
-                        actions=gtk.gdk.ACTION_COPY)
+        w.drag_dest_set(flags=Gtk.DestDefaults.ALL,
+                        targets=[Gtk.TargetEntry('text/uri-list', 0, 0)],
+                        actions=Gdk.DragAction.COPY)
         def recv(widget, context, x, y, selection,
                        targetType, time):
             subUri = URIRef(selection.data.strip())
@@ -295,7 +301,7 @@
         log.debug("%s table children showing" % len(master.get_children()))
         
     def refreshTheme(self):
-        gtk.rc_reparse_all()
+        Gtk.rc_reparse_all()
         reactor.callLater(1, self.refreshTheme)
 
     def onSubtermChildAdded(self, subtermsTable, *args):
@@ -360,8 +366,8 @@
             ('update period', lambda t: "%.1fms"%(t*1000)),
             ('update status', lambda x: str(x)),
             ]):
-            key = gtk.Label("%s:" % signame)
-            value = gtk.Label("")
+            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)
@@ -457,6 +463,7 @@
     start = Main(graph, opts, session, curveset, music)
     out = Output(graph, session, music, curveset, start.currentSubterms)
 
+
     dispatcher.send("show all")
         
     if opts.startup_only:
--- a/lib/ipython_view.py	Sun Jun 01 10:39:17 2014 +0000
+++ b/lib/ipython_view.py	Sun Jun 01 20:35:38 2014 +0000
@@ -15,11 +15,12 @@
 # this file is a modified version of source code from the Accerciser project
 # http://live.gnome.org/accerciser
  
-import gtk
+from gi.repository import Gtk
+from gi.repository import Gdk
 import re
 import sys
 import os
-import pango
+from gi.repository import Pango
 from StringIO import StringIO
  
 try:
@@ -155,10 +156,10 @@
       output.close()
       input.close()
  
-class ConsoleView(gtk.TextView):
+class ConsoleView(Gtk.TextView):
   def __init__(self):
-    gtk.TextView.__init__(self)
-    self.modify_font(pango.FontDescription('Mono'))
+    Gtk.TextView.__init__(self)
+    self.modify_font(Pango.FontDescription('Mono'))
     self.set_cursor_visible(True)
     self.text_buffer = self.get_buffer()
     self.mark = self.text_buffer.create_mark('scroll_mark', 
@@ -267,21 +268,21 @@
     return self.getCurrentLine()
  
   def keyPress(self, widget, event):
-    if event.state & gtk.gdk.CONTROL_MASK and event.keyval == 99:
+    if event.state & Gdk.ModifierType.CONTROL_MASK and event.keyval == 99:
       self.interrupt = True
       self._processLine()
       return True
-    elif event.keyval == gtk.keysyms.Return:
+    elif event.keyval == Gtk.keysyms.Return:
       self._processLine()
       return True
-    elif event.keyval == gtk.keysyms.Up:
+    elif event.keyval == Gtk.keysyms.Up:
       self.changeLine(self.historyBack())
       return True
-    elif event.keyval == gtk.keysyms.Down:
+    elif event.keyval == Gtk.keysyms.Down:
       self.changeLine(self.historyForward())
       return True
     # todo: Home needs to advance past the ipython prompt
-    elif event.keyval == gtk.keysyms.Tab:
+    elif event.keyval == Gtk.keysyms.Tab:
       if not self.getCurrentLine().strip():
         return False
       completed, possibilities = self.complete(self.getCurrentLine())
--- a/light9/curvecalc/curvecalc.glade	Sun Jun 01 10:39:17 2014 +0000
+++ b/light9/curvecalc/curvecalc.glade	Sun Jun 01 20:35:38 2014 +0000
@@ -1,7 +1,20 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.16.1 -->
 <interface>
-  <requires lib="gtk+" version="2.24"/>
-  <!-- interface-naming-policy toplevel-contextual -->
+  <requires lib="gtk+" version="3.10"/>
+  <object class="GtkAccelGroup" id="accelgroup1"/>
+  <object class="GtkAdjustment" id="adjustment1">
+    <property name="upper">100</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
+  <object class="GtkTextBuffer" id="help">
+    <property name="text">Mousewheel zoom; C-p play/pause music at mouse
+Drag sub into curve area for new curve+subterm
+Keys in a selected curve: C to collapse; R to rebuild broken canvas widget; 1..5 add point at time cursor; q,w,e,r,t,y set marker at time cursor
+Curve point bindings: B1 drag point; C-B1 curve add point; S-B1 sketch points; 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="GtkWindow" id="MainWindow">
     <property name="can_focus">False</property>
     <child>
@@ -14,9 +27,9 @@
             <property name="can_focus">False</property>
             <child>
               <object class="GtkMenuItem" id="menuitem1">
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="use_action_appearance">False</property>
                 <property name="label" translatable="yes">_Curvecalc</property>
                 <property name="use_underline">True</property>
                 <child type="submenu">
@@ -26,25 +39,25 @@
                     <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>
-                        <property name="use_action_appearance">False</property>
                         <property name="use_underline">True</property>
                         <property name="use_stock">True</property>
+                        <signal name="activate" handler="onSave" swapped="no"/>
                         <accelerator key="s" signal="activate" modifiers="GDK_CONTROL_MASK"/>
-                        <signal name="activate" handler="onSave" swapped="no"/>
                       </object>
                     </child>
                     <child>
                       <object class="GtkImageMenuItem" id="imagemenuitem5">
                         <property name="label">gtk-quit</property>
+                        <property name="use_action_appearance">False</property>
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="use_action_appearance">False</property>
                         <property name="use_underline">True</property>
                         <property name="use_stock">True</property>
+                        <signal name="activate" handler="onQuit" swapped="no"/>
                         <accelerator key="q" signal="activate" modifiers="GDK_CONTROL_MASK"/>
-                        <signal name="activate" handler="onQuit" swapped="no"/>
                       </object>
                     </child>
                   </object>
@@ -53,9 +66,9 @@
             </child>
             <child>
               <object class="GtkMenuItem" id="menuitem7">
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="use_action_appearance">False</property>
                 <property name="label" translatable="yes">_Edit</property>
                 <property name="use_underline">True</property>
                 <child type="submenu">
@@ -65,9 +78,9 @@
                     <child>
                       <object class="GtkImageMenuItem" id="imagemenuitem1">
                         <property name="label">gtk-cut</property>
+                        <property name="use_action_appearance">False</property>
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="use_action_appearance">False</property>
                         <property name="use_underline">True</property>
                         <property name="use_stock">True</property>
                       </object>
@@ -75,9 +88,9 @@
                     <child>
                       <object class="GtkImageMenuItem" id="imagemenuitem3">
                         <property name="label">gtk-copy</property>
+                        <property name="use_action_appearance">False</property>
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="use_action_appearance">False</property>
                         <property name="use_underline">True</property>
                         <property name="use_stock">True</property>
                       </object>
@@ -85,9 +98,9 @@
                     <child>
                       <object class="GtkImageMenuItem" id="imagemenuitem4">
                         <property name="label">gtk-paste</property>
+                        <property name="use_action_appearance">False</property>
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="use_action_appearance">False</property>
                         <property name="use_underline">True</property>
                         <property name="use_stock">True</property>
                       </object>
@@ -95,13 +108,13 @@
                     <child>
                       <object class="GtkImageMenuItem" id="imagemenuitem6">
                         <property name="label">gtk-delete</property>
+                        <property name="use_action_appearance">False</property>
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="use_action_appearance">False</property>
                         <property name="use_underline">True</property>
                         <property name="use_stock">True</property>
+                        <signal name="activate" handler="onDelete" swapped="no"/>
                         <accelerator key="Delete" signal="activate"/>
-                        <signal name="activate" handler="onDelete" swapped="no"/>
                       </object>
                     </child>
                   </object>
@@ -110,32 +123,31 @@
             </child>
             <child>
               <object class="GtkMenuItem" id="menuitem13">
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="use_action_appearance">False</property>
                 <property name="label" translatable="yes">_Create</property>
                 <property name="use_underline">True</property>
                 <child type="submenu">
                   <object class="GtkMenu" id="menu6">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="ubuntu_local">True</property>
                     <child>
                       <object class="GtkMenuItem" id="menuitem14">
+                        <property name="use_action_appearance">False</property>
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="use_action_appearance">False</property>
                         <property name="label" translatable="yes">Curve...</property>
                         <property name="use_underline">True</property>
+                        <signal name="activate" handler="onNewCurve" swapped="no"/>
                         <accelerator key="n" signal="activate" modifiers="GDK_CONTROL_MASK"/>
-                        <signal name="activate" handler="onNewCurve" swapped="no"/>
                       </object>
                     </child>
                     <child>
                       <object class="GtkMenuItem" id="menuitem15">
+                        <property name="use_action_appearance">False</property>
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="use_action_appearance">False</property>
                         <property name="label" translatable="yes">Subterm...</property>
                         <property name="use_underline">True</property>
                         <signal name="activate" handler="onNewSubterm" swapped="no"/>
@@ -147,9 +159,9 @@
             </child>
             <child>
               <object class="GtkMenuItem" id="menuitem2">
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="use_action_appearance">False</property>
                 <property name="label" translatable="yes">_View</property>
                 <property name="use_underline">True</property>
                 <child type="submenu">
@@ -158,60 +170,60 @@
                     <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="use_action_appearance">False</property>
                         <property name="label" translatable="yes">See current time</property>
                         <property name="use_underline">True</property>
+                        <signal name="activate" handler="onSeeCurrentTime" swapped="no"/>
                         <accelerator key="Escape" signal="activate"/>
-                        <signal name="activate" handler="onSeeCurrentTime" swapped="no"/>
                       </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="use_action_appearance">False</property>
                         <property name="label" translatable="yes">See from current time -&gt; end</property>
                         <property name="use_underline">True</property>
+                        <signal name="activate" handler="onSeeTimeUntilEnd" swapped="no"/>
                         <accelerator key="Escape" signal="activate" modifiers="GDK_SHIFT_MASK"/>
-                        <signal name="activate" handler="onSeeTimeUntilEnd" swapped="no"/>
                       </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="use_action_appearance">False</property>
                         <property name="label" translatable="yes">Zoom all</property>
                         <property name="use_underline">True</property>
+                        <signal name="activate" handler="onZoomAll" swapped="no"/>
                         <accelerator key="Escape" signal="activate" modifiers="GDK_CONTROL_MASK"/>
-                        <signal name="activate" handler="onZoomAll" swapped="no"/>
                       </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="use_action_appearance">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="use_action_appearance">False</property>
                         <property name="label" translatable="yes">Zoom out (wheel down)</property>
                         <property name="use_underline">True</property>
                       </object>
                     </child>
                     <child>
                       <object class="GtkMenuItem" id="menuitem17">
+                        <property name="use_action_appearance">False</property>
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="use_action_appearance">False</property>
                         <property name="label" translatable="yes">Redraw curves</property>
                         <property name="use_underline">True</property>
                         <signal name="activate" handler="onRedrawCurves" swapped="no"/>
@@ -223,9 +235,9 @@
             </child>
             <child>
               <object class="GtkMenuItem" id="menuitem3">
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="use_action_appearance">False</property>
                 <property name="label" translatable="yes">_Playback</property>
                 <property name="use_underline">True</property>
                 <child type="submenu">
@@ -234,13 +246,13 @@
                     <property name="can_focus">False</property>
                     <child>
                       <object class="GtkMenuItem" id="menuitem5">
+                        <property name="use_action_appearance">False</property>
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="use_action_appearance">False</property>
                         <property name="label" translatable="yes">_Play/pause</property>
                         <property name="use_underline">True</property>
+                        <signal name="activate" handler="onPlayPause" swapped="no"/>
                         <accelerator key="p" signal="activate" modifiers="GDK_CONTROL_MASK"/>
-                        <signal name="activate" handler="onPlayPause" swapped="no"/>
                       </object>
                     </child>
                   </object>
@@ -249,9 +261,9 @@
             </child>
             <child>
               <object class="GtkMenuItem" id="menuitem4">
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="use_action_appearance">False</property>
                 <property name="label" translatable="yes">Poin_ts</property>
                 <property name="use_underline">True</property>
                 <child type="submenu">
@@ -260,9 +272,9 @@
                     <property name="can_focus">False</property>
                     <child>
                       <object class="GtkMenuItem" id="menuitem6">
+                        <property name="use_action_appearance">False</property>
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="use_action_appearance">False</property>
                         <property name="label" translatable="yes">Delete</property>
                         <property name="use_underline">True</property>
                       </object>
@@ -273,25 +285,24 @@
             </child>
             <child>
               <object class="GtkMenuItem" id="menuitem16">
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="use_action_appearance">False</property>
                 <property name="label" translatable="yes">Debug</property>
                 <property name="use_underline">True</property>
                 <child type="submenu">
                   <object class="GtkMenu" id="menu7">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="ubuntu_local">True</property>
                     <child>
                       <object class="GtkCheckMenuItem" id="checkmenuitem1">
+                        <property name="use_action_appearance">False</property>
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="use_action_appearance">False</property>
                         <property name="label" translatable="yes">Python console</property>
                         <property name="use_underline">True</property>
+                        <signal name="toggled" handler="onPythonConsole" swapped="no"/>
                         <accelerator key="p" signal="activate" modifiers="GDK_SHIFT_MASK | GDK_CONTROL_MASK"/>
-                        <signal name="toggled" handler="onPythonConsole" swapped="no"/>
                       </object>
                     </child>
                   </object>
@@ -340,11 +351,11 @@
             <child>
               <object class="GtkLinkButton" id="playerSong">
                 <property name="label" translatable="yes">(song)</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="has_tooltip">True</property>
-                <property name="use_action_appearance">False</property>
                 <property name="relief">none</property>
                 <property name="xalign">0</property>
                 <property name="uri">http://glade.gnome.org</property>
@@ -358,10 +369,11 @@
             <child>
               <object class="GtkCheckButton" id="followPlayerSongChoice">
                 <property name="label" translatable="yes">follow player song choice</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>
@@ -406,10 +418,10 @@
                         <child>
                           <object class="GtkButton" id="button22">
                             <property name="label">gtk-add</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="use_stock">True</property>
                             <signal name="clicked" handler="onNewCurve" swapped="no"/>
                           </object>
@@ -422,10 +434,10 @@
                         <child>
                           <object class="GtkButton" id="button7">
                             <property name="label" translatable="yes">Collapse all</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>
                             <signal name="clicked" handler="onCollapseAll" swapped="no"/>
                           </object>
                           <packing>
@@ -437,10 +449,10 @@
                         <child>
                           <object class="GtkButton" id="button6">
                             <property name="label" translatable="yes">Collapse none	</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>
                             <signal name="clicked" handler="onCollapseNone" swapped="no"/>
                           </object>
                           <packing>
@@ -466,9 +478,10 @@
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkVBox" id="zoomControlBox">
+                      <object class="GtkBox" id="zoomControlBox">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
+                        <property name="orientation">vertical</property>
                         <child>
                           <object class="GtkLabel" id="zoomControl">
                             <property name="visible">True</property>
@@ -489,6 +502,9 @@
                       </packing>
                     </child>
                     <child>
+                      <placeholder/>
+                    </child>
+                    <child>
                       <object class="GtkScrolledWindow" id="scrolledwindow1">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
@@ -524,7 +540,7 @@
                       <packing>
                         <property name="expand">True</property>
                         <property name="fill">True</property>
-                        <property name="position">2</property>
+                        <property name="position">3</property>
                       </packing>
                     </child>
                   </object>
@@ -570,7 +586,6 @@
                                 <property name="can_focus">False</property>
                                 <property name="n_columns">2</property>
                                 <signal name="add" handler="onSubtermChildAdded" swapped="no"/>
-                                <signal name="child-added" handler="onSubtermChildAdded" swapped="no"/>
                                 <signal name="map" handler="onSubtermsMap" swapped="no"/>
                                 <child>
                                   <placeholder/>
@@ -578,6 +593,18 @@
                                 <child>
                                   <placeholder/>
                                 </child>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                                <child>
+                                  <placeholder/>
+                                </child>
                               </object>
                             </child>
                           </object>
@@ -613,10 +640,10 @@
                         <child>
                           <object class="GtkButton" id="button2">
                             <property name="label">gtk-add</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="use_stock">True</property>
                             <signal name="clicked" handler="onNewSubterm" swapped="no"/>
                           </object>
@@ -679,6 +706,18 @@
                     <child>
                       <placeholder/>
                     </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
                   </object>
                 </child>
                 <child type="label">
@@ -721,120 +760,12 @@
       </object>
     </child>
   </object>
-  <object class="GtkAccelGroup" id="accelgroup1"/>
-  <object class="GtkAdjustment" id="adjustment1">
-    <property name="upper">100</property>
-    <property name="step_increment">1</property>
-    <property name="page_increment">10</property>
-  </object>
-  <object class="GtkTextBuffer" id="help">
-    <property name="text">Mousewheel zoom; C-p play/pause music at mouse
-Drag sub into curve area for new curve+subterm
-Keys in a selected curve: C to collapse; R to rebuild broken canvas widget; 1..5 add point at time cursor; q,w,e,r,t,y set marker at time cursor
-Curve point bindings: B1 drag point; C-B1 curve add point; S-B1 sketch points; 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="GtkListStore" id="liststore1"/>
-  <object class="GtkDialog" id="newCurve">
-    <property name="can_focus">False</property>
-    <property name="border_width">5</property>
-    <property name="title" translatable="yes">New curve</property>
-    <property name="modal">True</property>
-    <property name="window_position">mouse</property>
-    <property name="type_hint">normal</property>
-    <child internal-child="vbox">
-      <object class="GtkVBox" id="dialog-vbox1">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="spacing">2</property>
-        <child internal-child="action_area">
-          <object class="GtkHButtonBox" id="dialog-action_area1">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="layout_style">end</property>
-            <child>
-              <object class="GtkButton" id="button5">
-                <property name="label">gtk-cancel</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="use_stock">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="button4">
-                <property name="label">gtk-add</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="can_default">True</property>
-                <property name="has_default">True</property>
-                <property name="receives_default">True</property>
-                <property name="use_action_appearance">False</property>
-                <property name="use_stock">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="pack_type">end</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkLabel" id="label12">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="label" translatable="yes">Name for new curve</property>
-          </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkEntry" id="newCurveName">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="has_focus">True</property>
-            <property name="is_focus">True</property>
-            <property name="invisible_char">●</property>
-            <property name="activates_default">True</property>
-            <property name="primary_icon_activatable">False</property>
-            <property name="secondary_icon_activatable">False</property>
-            <property name="primary_icon_sensitive">True</property>
-            <property name="secondary_icon_sensitive">True</property>
-          </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">2</property>
-          </packing>
-        </child>
-      </object>
-    </child>
-    <action-widgets>
-      <action-widget response="2">button5</action-widget>
-      <action-widget response="1">button4</action-widget>
-    </action-widgets>
-  </object>
   <object class="GtkDialog" id="newSubterm">
     <property name="can_focus">False</property>
     <property name="border_width">5</property>
@@ -844,22 +775,22 @@
     <property name="window_position">mouse</property>
     <property name="type_hint">normal</property>
     <child internal-child="vbox">
-      <object class="GtkVBox" id="dialog-vbox3">
+      <object class="GtkBox" id="dialog-vbox3">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
         <property name="spacing">2</property>
         <child internal-child="action_area">
-          <object class="GtkHButtonBox" id="dialog-action_area3">
+          <object class="GtkButtonBox" id="dialog-action_area3">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
             <property name="layout_style">end</property>
             <child>
               <object class="GtkButton" id="button12">
                 <property name="label">gtk-cancel</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="use_stock">True</property>
               </object>
               <packing>
@@ -871,12 +802,12 @@
             <child>
               <object class="GtkButton" id="button3">
                 <property name="label">gtk-add</property>
+                <property name="use_action_appearance">False</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="can_default">True</property>
                 <property name="has_default">True</property>
                 <property name="receives_default">True</property>
-                <property name="use_action_appearance">False</property>
                 <property name="use_stock">True</property>
               </object>
               <packing>
@@ -918,6 +849,11 @@
                 <property name="model">liststore1</property>
                 <property name="has_entry">True</property>
                 <property name="entry_text_column">0</property>
+                <child internal-child="entry">
+                  <object class="GtkEntry" id="combobox-entry1">
+                    <property name="can_focus">False</property>
+                  </object>
+                </child>
               </object>
               <packing>
                 <property name="expand">True</property>
@@ -928,11 +864,12 @@
             <child>
               <object class="GtkCheckButton" id="newSubtermMakeCurve">
                 <property name="label" translatable="yes">_Make new curve with the same name</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="use_underline">True</property>
+                <property name="xalign">0.5</property>
                 <property name="active">True</property>
                 <property name="draw_indicator">True</property>
               </object>
@@ -956,6 +893,104 @@
       <action-widget response="1">button3</action-widget>
     </action-widgets>
   </object>
+  <object class="GtkDialog" id="newCurve">
+    <property name="can_focus">False</property>
+    <property name="border_width">5</property>
+    <property name="title" translatable="yes">New curve</property>
+    <property name="modal">True</property>
+    <property name="window_position">mouse</property>
+    <property name="type_hint">normal</property>
+    <child internal-child="vbox">
+      <object class="GtkBox" id="dialog-vbox1">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="spacing">2</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="button5">
+                <property name="label">gtk-cancel</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_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="button4">
+                <property name="label">gtk-add</property>
+                <property name="use_action_appearance">False</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="has_default">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="label12">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes">Name for new curve</property>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="newCurveName">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="has_focus">True</property>
+            <property name="is_focus">True</property>
+            <property name="invisible_char">●</property>
+            <property name="activates_default">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">2</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="2">button5</action-widget>
+      <action-widget response="1">button4</action-widget>
+    </action-widgets>
+  </object>
+  <object class="GtkSizeGroup" id="sizegroup1"/>
+  <object class="GtkSizeGroup" id="sizegroup2"/>
+  <object class="GtkTextBuffer" id="textbuffer1">
+    <property name="text" translatable="yes">song01(t)</property>
+  </object>
   <object class="GtkVBox" id="vbox2">
     <property name="visible">True</property>
     <property name="can_focus">False</property>
@@ -987,9 +1022,4 @@
       </packing>
     </child>
   </object>
-  <object class="GtkSizeGroup" id="sizegroup1"/>
-  <object class="GtkSizeGroup" id="sizegroup2"/>
-  <object class="GtkTextBuffer" id="textbuffer1">
-    <property name="text" translatable="yes">song01(t)</property>
-  </object>
 </interface>
--- a/light9/curvecalc/curveview.py	Sun Jun 01 10:39:17 2014 +0000
+++ b/light9/curvecalc/curveview.py	Sun Jun 01 20:35:38 2014 +0000
@@ -1,12 +1,15 @@
 from __future__ import division
 import math, time, logging
-import gtk, goocanvas
+from gi.repository import Gtk
+from gi.repository import GObject
+from gi.repository import Gdk
+from gi.repository import GooCanvas
 import louie as dispatcher
 from rdflib import Literal
 from light9.curvecalc.zoomcontrol import RegionZoom
 from light9.curvecalc import cursors
 from light9.curvecalc.curve import introPad, postPad
-from light9.dmxchanedit import gradient
+from lib.goocanvas_compat import Points, polyline_new_line
 
 log = logging.getLogger()
 print "curveview.py toplevel"
@@ -89,23 +92,23 @@
         self.getWorldTime = getWorldTime
         self.getDragRange = getDragRange
         self.getWorldValue = getWorldValue
-        self.grp = goocanvas.Group(parent=parent)
+        self.grp = GooCanvas.CanvasGroup(parent=parent)
         
-        self.title = goocanvas.Text(parent=self.grp, text="selectmanip",
+        self.title = GooCanvas.CanvasText(parent=self.grp, text="selectmanip",
                                     x=10, y=10, fill_color='white', font="ubuntu 10")
 
-        self.bbox = goocanvas.Rect(parent=self.grp,
+        self.bbox = GooCanvas.CanvasRect(parent=self.grp,
                                    fill_color_rgba=0xffff0030,
                                    line_width=0)
 
-        self.xTrans = goocanvas.Polyline(parent=self.grp, close_path=True,
+        self.xTrans = polyline_new_line(parent=self.grp, close_path=True,
                                          fill_color_rgba=0xffffff88,
                                          )
-        self.centerScale = goocanvas.Polyline(parent=self.grp, close_path=True,
+        self.centerScale = polyline_new_line(parent=self.grp, close_path=True,
                                               fill_color_rgba=0xffffff88,
                                          )
 
-        thickLine = lambda: goocanvas.Polyline(parent=self.grp,
+        thickLine = lambda: polyline_new_line(parent=self.grp,
                                                stroke_color_rgba=0xffffccff,
                                                line_width=6)
         self.leftScale = thickLine()
@@ -225,8 +228,8 @@
         b.height = min(max(p[1] for p in pts) - b.y + margin,
                        self.getCanvasSize().height - b.y - 1)
 
-        multi = (goocanvas.ITEM_VISIBLE if len(pts) > 1 else
-                 goocanvas.ITEM_INVISIBLE)
+        multi = (GooCanvas.CanvasItemVisibility.VISIBLE if len(pts) > 1 else
+                 GooCanvas.CanvasItemVisibility.INVISIBLE)
         b.visibility = multi
         self.leftScale.props.visibility = multi
         self.rightScale.props.visibility = multi
@@ -241,17 +244,17 @@
         midY = self.getCanvasSize().height * .5
         loY = self.getCanvasSize().height * .8
 
-        self.leftScale.props.points = goocanvas.Points([
+        self.leftScale.props.points = Points([
             (b.x, b.y), (b.x, b.y + b.height)])
-        self.rightScale.props.points = goocanvas.Points([
+        self.rightScale.props.points = Points([
             (b.x + b.width, b.y), (b.x + b.width, b.y + b.height)])
 
-        self.topScale.props.points = goocanvas.Points([
+        self.topScale.props.points = Points([
             (b.x, b.y), (b.x + b.width, b.y)])
 
         self.updateXTrans(centerX, midY)
 
-        self.centerScale.props.points = goocanvas.Points([
+        self.centerScale.props.points = Points([
             (centerX - 5, loY - 5),
             (centerX + 5, loY - 5),
             (centerX + 5, loY + 5),
@@ -282,7 +285,7 @@
             (x2, y4)
             ]
 
-        self.xTrans.props.points = goocanvas.Points(shape)
+        self.xTrans.props.points = Points(shape)
 
     def destroy(self):
         self.grp.remove()
@@ -355,22 +358,22 @@
         if hasattr(self, 'widget'):
             self.widget.destroy()
             self._time = -999
-            print "rebuilding canvas"
+            print "rebuilding canvas, destroyed old widget"
 
         self.timelineLine = self.curveGroup = self.selectManip = None
-        self.widget = gtk.EventBox()
+        self.widget = Gtk.EventBox()
         self.widget.set_can_focus(True)
-        self.widget.add_events(gtk.gdk.KEY_PRESS_MASK |
-                               gtk.gdk.FOCUS_CHANGE_MASK)
+        self.widget.add_events(Gdk.EventMask.KEY_PRESS_MASK |
+                               Gdk.EventMask.FOCUS_CHANGE_MASK)
         self.onFocusOut()
 
-        box = gtk.VBox()
+        box = Gtk.VBox()
         box.set_border_width(1)
         self.widget.add(box)
         box.show()
         
-        self.canvas = goocanvas.Canvas()
-        box.pack_start(self.canvas)
+        self.canvas = GooCanvas.Canvas()
+        box.pack_start(self.canvas, expand=True, fill=True, padding=0)
         self.canvas.show()
 
         p = self.canvas.props
@@ -381,7 +384,7 @@
         self.root = self.canvas.get_root_item()
 
         self.canvas.connect("size-allocate", self.update_curve)
-        self.canvas.connect("expose-event", self.onExpose)
+        self.canvas.connect("draw", self.onExpose)
 
         self.canvas.connect("leave-notify-event", self.onLeave)
         self.canvas.connect("enter-notify-event", self.onEnter)
@@ -394,7 +397,7 @@
 
         self.widget.connect("focus-in-event", self.onFocusIn)
         self.widget.connect("focus-out-event", self.onFocusOut)
-        #self.widget.connect("event", self.onAny)       
+        self.widget.connect("event", self.onAny)
 
     def onAny(self, w, event):
         print "   %s on %s" % (event, w)
@@ -402,10 +405,10 @@
     def onFocusIn(self, *args):
         dispatcher.send("all curves lose selection", butNot=self)
 
-        self.widget.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("red"))
+        self.widget.modify_bg(Gtk.StateFlags.NORMAL, Gdk.color_parse("red"))
 
     def onFocusOut(self, widget=None, event=None):
-        self.widget.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("gray30"))
+        self.widget.modify_bg(Gtk.StateFlags.NORMAL, Gdk.color_parse("gray30"))
 
         # you'd think i'm unselecting when we lose focus, but we also
         # lose focus when the user moves off the toplevel window, and
@@ -420,6 +423,7 @@
             self.add_marker((self.current_time(), event.string))
 
     def onExpose(self, *args):
+        print "onExpose for %s, culled=%s" % (self, self.culled)
         if self.culled:
             self.update_curve()
 
@@ -436,10 +440,11 @@
         # click
 
         self.widget.grab_focus()
-        
-        if event.get_state() & gtk.gdk.CONTROL_MASK:
+
+        _, flags = event.get_state()
+        if flags & Gdk.ModifierType.CONTROL_MASK:
             self.new_point_at_mouse(event)
-        elif event.get_state() & gtk.gdk.SHIFT_MASK:
+        elif flags & Gdk.ModifierType.SHIFT_MASK:
             self.sketch_press(event)
         else:
             self.select_press(event)
@@ -630,10 +635,10 @@
     def update_time_bar(self, t):
 
         if not getattr(self, 'timelineLine', None):
-            self.timelineGroup = goocanvas.Group(parent=self.root)
-            self.timelineLine = goocanvas.Polyline(
+            self.timelineGroup = GooCanvas.CanvasGroup(parent=self.root)
+            self.timelineLine = polyline_new_line(
                 parent=self.timelineGroup,
-                points=goocanvas.Points([(0,0), (0,0)]),
+                points=Points([(0,0), (0,0)]),
                 line_width=2, stroke_color='red')
 
         try:
@@ -641,7 +646,7 @@
                    self.screen_from_world((t, 1))]
         except ZeroDivisionError:
             pts = [(-1, -1), (-1, -1)]
-        self.timelineLine.set_property('points', goocanvas.Points(pts))
+        self.timelineLine.set_property('points', Points(pts))
         
         self._time = t
         if self.knobEnabled:
@@ -656,9 +661,10 @@
                 dispatcher.send("knob out", value=prevKey[1], curve=self.curve)
 
     def canvasIsVisible(self):
+        print "test canvasIsVisible"
         if not hasattr(self, "scrollWin"):
             self.scrollWin = self.canvas
-            while not isinstance(self.scrollWin, gtk.ScrolledWindow):
+            while not isinstance(self.scrollWin, Gtk.ScrolledWindow):
                 self.scrollWin = self.scrollWin.get_parent()
 
         sw = self.scrollWin
@@ -668,17 +674,22 @@
 
         coords = self.canvas.translate_coordinates(top, 0, 0)
         if not coords: # probably broken after a reload()
+            print "  canvas coords failed"
             return False
         cany1 = coords[1]
         cany2 = cany1 + self.canvas.get_allocation().height
-        return not (cany2 < visy1 or cany1 > visy2)
+        ret = not (cany2 < visy1 or cany1 > visy2)
+        print "  return %s" % ret
+        return ret
         
     def update_curve(self, *args):
         if not self.redrawsEnabled:
+            print "update_curve skipping1"
             return
 
         if not self.canvasIsVisible():
             self.culled = True
+            print "update_curve skipping2"
             return
         self.culled = False
         
@@ -692,14 +703,16 @@
         visible_points = [self.curve.points[i] for i in visible_idxs]
 
         if getattr(self, 'curveGroup', None):
+            print "rm old curveGroup"
             self.curveGroup.remove()
-        self.curveGroup = goocanvas.Group(parent=self.root)
+        self.curveGroup = GooCanvas.CanvasGroup(parent=self.root)
 
         # this makes gtk quietly stop working. Getting called too early?
         #self.canvas.set_property("background-color",
         #                         "gray20" if self.curve.muted else "black")
 
         self.update_time_bar(self._time)
+        print "drawing! height=%s" % self.size.height
         if self.size.height < 40:
             self._draw_line(visible_points, area=True)
         else:
@@ -732,10 +745,10 @@
             }
         for t, name in pts:
             x = int(self.screen_from_world((t,0))[0]) + .5
-            goocanvas.polyline_new_line(self.curveGroup,
-                                        x, 0, x, self.size.height,
-                                        line_width=.4 if name in 'rty' else .8,
-                                        stroke_color=colorMap.get(name, 'gray'))
+            polyline_new_line(self.curveGroup,
+                              x, 0, x, self.size.height,
+                              line_width=.4 if name in 'rty' else .8,
+                              stroke_color=colorMap.get(name, 'gray'))
 
     def _draw_time_tics(self,visible_x):
         tic = self._draw_one_tic
@@ -763,14 +776,14 @@
             x = -100
             
         ht = self.size.height
-        goocanvas.polyline_new_line(self.curveGroup,
+        polyline_new_line(self.curveGroup,
                                     x, ht,
                                     x, ht - 20,
                                     line_width=.5,
                                     stroke_color='gray70')
-        goocanvas.Text(parent=self.curveGroup,
+        GooCanvas.CanvasText(parent=self.curveGroup,
                        fill_color="white",
-                       anchor=gtk.ANCHOR_SOUTH,
+                       anchor=GooCanvas.CanvasAnchorType.SOUTH,
                        font="ubuntu 7",
                        x=x+3, y=ht-20,
                        text=label)
@@ -801,8 +814,8 @@
             except ZeroDivisionError:
                 base = -100
             base = base + linewidth / 2
-            goocanvas.Polyline(parent=self.curveGroup,
-                               points=goocanvas.Points(
+            polyline_new_line(parent=self.curveGroup,
+                               points=Points(
                                    [(linepts[0][0], base)] +
                                    linepts +
                                    [(linepts[-1][0], base)]),
@@ -811,8 +824,8 @@
                                fill_color="green",
                                )
 
-        self.pl = goocanvas.Polyline(parent=self.curveGroup,
-                                     points=goocanvas.Points(linepts),
+        self.pl = polyline_new_line(parent=self.curveGroup,
+                                     points=Points(linepts),
                                      line_width=linewidth,
                                      stroke_color=fill,
                                      )
@@ -826,7 +839,7 @@
                 p = self.screen_from_world(p)
             except ZeroDivisionError:
                 p = (-100, -100)
-            dot = goocanvas.Rect(parent=self.curveGroup,
+            dot = GooCanvas.CanvasRect(parent=self.curveGroup,
                                  x=int(p[0] - rad) + .5,
                                  y=int(p[1] - rad) + .5,
                                  width=rad * 2, height=rad * 2,
@@ -838,7 +851,7 @@
 
             if worldp[1] == 0:
                 rad += 3
-                goocanvas.Ellipse(parent=self.curveGroup,
+                GooCanvas.CanvasEllipse(parent=self.curveGroup,
                                   center_x=p[0],
                                   center_y=p[1],
                                   radius_x=rad,
@@ -940,7 +953,7 @@
     def onMotion(self, widget, event):
         self.lastMouseX = event.x
 
-        if event.state & gtk.gdk.SHIFT_MASK and 1: # and B1
+        if event.state & Gdk.ModifierType.SHIFT_MASK and 1: # and B1
             self.sketch_motion(event)
             return
 
@@ -994,12 +1007,12 @@
     def onScroll(self, widget, event):
         t = self.world_from_screen(event.x, 0)[0]
         self.zoomControl.zoom_about_mouse(
-            t, factor=1.5 if event.direction == gtk.gdk.SCROLL_DOWN else 1/1.5)
+            t, factor=1.5 if event.direction == Gdk.ScrollDirection.DOWN else 1/1.5)
         
     def onRelease(self, widget, event):
         self.print_state("dotrelease")
 
-        if event.state & gtk.gdk.SHIFT_MASK: # relese-B1
+        if event.state & Gdk.ModifierType.SHIFT_MASK: # relese-B1
             self.sketch_release(event)
             return
 
@@ -1020,16 +1033,16 @@
     """
     def __init__(self, name, curve, markers, slider, knobEnabled, zoomControl):
         self.name = name
-        self.box = gtk.VBox()
+        self.box = Gtk.VBox()
         self.box.set_border_width(1)
 
-        self.cols = gtk.HBox()
+        self.cols = Gtk.HBox()
         self.box.add(self.cols)
         
-        controls = gtk.Frame()
+        controls = Gtk.Frame()
         controls.set_size_request(115, -1)
-        controls.set_shadow_type(gtk.SHADOW_OUT)
-        self.cols.pack_start(controls, expand=False)
+        controls.set_shadow_type(Gtk.ShadowType.OUT)
+        self.cols.pack_start(controls, expand=False, fill=True, padding=0)
         self.setupControls(controls, name, curve, slider)
 
         self.curveView = Curveview(curve, markers, knobEnabled=knobEnabled,
@@ -1056,27 +1069,27 @@
     def initCurveView(self):
         self.curveView.widget.show()
         self.curveView.widget.set_size_request(-1, 100)
-        self.cols.pack_start(self.curveView.widget, expand=True)       
+        self.cols.pack_start(self.curveView.widget, expand=True, fill=True, padding=0)       
         
     def setupControls(self, controls, name, curve, slider):
-        box = gtk.VBox()
+        box = Gtk.VBox()
         controls.add(box)
         
         txt = "curve '%s'" % name
         if len(name) > 7:
             txt = name
-        curve_name_label = gtk.Label(txt)
-        box.pack_start(curve_name_label)
+        curve_name_label = Gtk.Label(txt)
+        box.pack_start(curve_name_label, expand=True, fill=True, padding=0)
 
-        bools = gtk.HBox()
-        box.pack_start(bools)
-        self.collapsed = gtk.CheckButton("C")
-        bools.pack_start(self.collapsed)
+        bools = Gtk.HBox()
+        box.pack_start(bools, expand=True, fill=True, padding=0)
+        self.collapsed = Gtk.CheckButton("C")
+        bools.pack_start(self.collapsed, expand=True, fill=True, padding=0)
         self.collapsed.connect("toggled", self.update_ui_to_collapsed_state)
         self.hideWhenCollapsed = [bools]
-        self.muted = gtk.CheckButton("M")
+        self.muted = Gtk.CheckButton("M")
         
-        bools.pack_start(self.muted)
+        bools.pack_start(self.muted, expand=True, fill=True, padding=0)
         self.muted.connect("toggled", self.sync_mute_to_curve)
         dispatcher.connect(self.mute_changed, 'mute changed', sender=curve)
 
@@ -1084,8 +1097,8 @@
         if slider is not None:
             # slider should have a checkbutton, defaults to off for
             # music tracks
-            self.sliderLabel = gtk.Label("Slider %s" % slider)
-            box.pack_start(self.sliderLabel)
+            self.sliderLabel = Gtk.Label("Slider %s" % slider)
+            box.pack_start(self.sliderLabel, expand=True, fill=True, padding=0)
 
         # widgets that need recoloring when we tint the row:
         #self.widgets = [leftside, self.collapsed, self.muted,
@@ -1142,7 +1155,6 @@
         self.zoomControl = light9.curvecalc.zoomcontrol.ZoomControl()
         zoomControlBox.add(self.zoomControl.widget)
         self.zoomControl.widget.show_all()
-
         for c in curveset.curveNamesInOrder():
             self.add_curve(c) 
 
@@ -1151,7 +1163,7 @@
         dispatcher.connect(self.set_featured_curves, "set_featured_curves")
         dispatcher.connect(self.song_has_changed, "song_has_changed")
         
-        self.newcurvename = gtk.EntryBuffer("", 0)
+        self.newcurvename = Gtk.EntryBuffer.new("", 0)
 
         eventBox = self.curvesVBox.get_parent()
         eventBox.connect("key-press-event", self.onKeyPress)
@@ -1184,7 +1196,7 @@
         """bring these curves to the top of the stack"""
         for n in curveNames[::-1]:
             self.curvesVBox.reorder_child(self.curveRow_from_name(n).box,
-                                          gtk.PACK_START)
+                                          Gtk.PACK_START)
         
     def onKeyPress(self, widget, event):
         if not self.live: # workaround for old instances living past reload()
@@ -1217,7 +1229,7 @@
         curve = self.curveset.curves[name]
         f = CurveRow(name, curve, self.curveset.markers,
                      slider, knobEnabled, self.zoomControl)
-        self.curvesVBox.pack_start(f.box)
+        self.curvesVBox.pack_start(f.box, expand=True, fill=True, padding=0)
         f.box.show_all()
         self.allCurveRows.add(f)
         f.curveView.goLive()
--- a/light9/curvecalc/subtermview.py	Sun Jun 01 10:39:17 2014 +0000
+++ b/light9/curvecalc/subtermview.py	Sun Jun 01 20:35:38 2014 +0000
@@ -1,4 +1,5 @@
-import gtk, logging
+import logging
+from gi.repository import Gtk
 from louie import dispatcher
 from rdflib import Literal, URIRef
 from light9.namespaces import L9
@@ -14,11 +15,11 @@
         self.saveContext = saveContext
         self.curveset = curveset
 
-        self.box = gtk.HBox()
+        self.box = Gtk.HBox()
 
-        self.entryBuffer = gtk.EntryBuffer("", -1)
-        self.entry = gtk.Entry()
-        self.error = gtk.Label("")
+        self.entryBuffer = Gtk.EntryBuffer("", -1)
+        self.entry = Gtk.Entry()
+        self.error = Gtk.Label("")
 
         self.box.pack_start(self.entry, expand=True)
         self.box.pack_start(self.error, expand=False)
@@ -67,12 +68,12 @@
         self.subterm = st
         self.graph = st.graph
 
-        self.label = gtk.Label("sub")
+        self.label = Gtk.Label("sub")
         self.graph.addHandler(self.setName)
 
-        self.label.drag_dest_set(flags=gtk.DEST_DEFAULT_ALL,
+        self.label.drag_dest_set(flags=Gtk.DEST_DEFAULT_ALL,
                             targets=[('text/uri-list', 0, 0)],
-                            actions=gtk.gdk.ACTION_COPY)
+                            actions=Gtk.gdk.ACTION_COPY)
         self.label.connect("drag-data-received", self.onDataReceivedOnLabel)
         
         sev = Subexprview(self.graph, self.subterm.uri, self.subterm.saveContext, curveset)
--- a/light9/curvecalc/zoomcontrol.py	Sun Jun 01 10:39:17 2014 +0000
+++ b/light9/curvecalc/zoomcontrol.py	Sun Jun 01 20:35:38 2014 +0000
@@ -1,7 +1,10 @@
 from __future__ import division
-import gtk, goocanvas
+from gi.repository import Gtk
+from gi.repository import GObject
+from gi.repository import GooCanvas
 import louie as dispatcher
 from light9.curvecalc import cursors 
+from lib.goocanvas_compat import Points, polyline_new_line
 
 class ZoomControl(object):
     """
@@ -52,7 +55,7 @@
     offset = property(**offset())
 
     def __init__(self, **kw):
-        self.widget = goocanvas.Canvas(bounds_padding=5)
+        self.widget = GooCanvas.Canvas(bounds_padding=5)
         self.widget.set_property("background-color", "gray60")
         self.widget.set_size_request(-1, 30)
         self.widget.props.x2 = 2000
@@ -67,16 +70,17 @@
         self.end = 250
 
         self.root = self.widget.get_root_item()
-        self.leftbrack = goocanvas.Polyline(parent=self.root,
+        self.leftbrack = polyline_new_line(parent=self.root,
                                             line_width=5, stroke_color='black')
-        self.rightbrack = goocanvas.Polyline(parent=self.root,
+        self.rightbrack = polyline_new_line(parent=self.root,
                                              line_width=5, stroke_color='black')
-        self.shade = goocanvas.Rect(parent=self.root,
+        self.shade = GooCanvas.CanvasRect(parent=self.root,
                                     fill_color='gray70',
                                     line_width=.5)
-        self.time = goocanvas.Polyline(parent=self.root,
+        self.time = polyline_new_line(parent=self.root,
                                        line_width=2,
                                        stroke_color='red')
+
         self.redrawzoom()
         self.widget.connect("size-allocate", self.redrawzoom)
 
@@ -146,8 +150,7 @@
         except ZeroDivisionError:
             x = -100
         self.time.set_property("points",
-                               goocanvas.Points([(x, 0),
-                                                 (x, self.size.height)]))
+                               Points([(x, 0), (x, self.size.height)]))
         
     def press(self,ev,attr):
         self.adjustingattr = attr
@@ -177,7 +180,7 @@
     def t_for_can(self,x):
         a, b = self.mintime, self.maxtime
         return (x - 20) / (self.size.width - 30) * (b - a) + a
-
+        
     def redrawzoom(self,*args):
         """redraw pieces based on start/end"""
         self.size = self.widget.get_allocation()
@@ -193,12 +196,12 @@
             # todo: set the zoom to some clear null state
             return
 
-        self.leftbrack.set_property("points", goocanvas.Points([
+        self.leftbrack.set_property("points", Points([
             (scan + lip, y1),
             (scan, y1),
             (scan, y2),
             (scan + lip, y2)]))
-        self.rightbrack.set_property("points", goocanvas.Points([
+        self.rightbrack.set_property("points", Points([
             (ecan - lip, y1),
             (ecan, y1),
             (ecan, y2),
@@ -214,7 +217,7 @@
     def redrawTics(self):
         if hasattr(self, 'ticsGroup'):
             self.ticsGroup.remove()
-        self.ticsGroup = goocanvas.Group(parent=self.root)
+        self.ticsGroup = GooCanvas.CanvasGroup(parent=self.root)
 
         lastx =- 1000
 
@@ -224,13 +227,13 @@
                 txt = str(t)
                 if lastx == -1000:
                     txt = txt + "sec"
-                goocanvas.Polyline(parent=self.ticsGroup,
-                                   points=goocanvas.Points([(x, 0), (x, 15)]),
+                GooCanvas.CanvasPolyline(parent=self.ticsGroup,
+                                   points=Points([(x, 0), (x, 15)]),
                                    line_width=.8,
                                    stroke_color='black')
-                goocanvas.Text(parent=self.ticsGroup,
+                GooCanvas.CanvasText(parent=self.ticsGroup,
                                x=x, y=self.size.height-1,
-                               anchor=gtk.ANCHOR_SOUTH,
+                               anchor=GooCanvas.CanvasAnchorType.SOUTH,
                                text=txt,
                                font='ubuntu 7')
                 lastx = x
--- a/light9/editchoicegtk.py	Sun Jun 01 10:39:17 2014 +0000
+++ b/light9/editchoicegtk.py	Sun Jun 01 20:35:38 2014 +0000
@@ -1,4 +1,5 @@
-import gtk
+from gi.repository import Gtk
+from gi.repository import Gdk
 from rdflib import URIRef
 
 class Local(object):
@@ -6,7 +7,7 @@
     manage. Set resourceObservable to Local to indicate that you're
     unlinked"""
 
-class EditChoice(gtk.HBox):
+class EditChoice(Gtk.HBox):
     """
     this is a gtk port of editchoice.EditChoice
     """
@@ -18,17 +19,22 @@
 
         # the outer box should have a distinctive border so it's more
         # obviously a special drop target
-        gtk.HBox.__init__(self)
-        self.pack_start(gtk.Label(label), expand=False)
+        Gtk.HBox.__init__(self)
+        self.pack_start(Gtk.Label(label),
+                        False, True, 0) #expand, fill, pad
 
         # this is just a label, but it should look like a physical
         # 'thing' (and gtk labels don't work as drag sources)
-        self.currentLink = gtk.Button("http://bar")
+        self.currentLink = Gtk.Button("http://bar")
+
+        self.pack_start(self.currentLink,
+                        True, True, 0) #expand, fill, pad
 
-        self.pack_start(self.currentLink)
 
-        self.unlinkButton = gtk.Button(label="Unlink")
-        self.pack_start(self.unlinkButton, expand=False)
+        self.unlinkButton = Gtk.Button(label="Unlink")
+        self.pack_start(self.unlinkButton,
+                        False, True, 0) #expand, fill pad
+
         self.unlinkButton.connect("clicked", self.onUnlink)
         
         self.show_all()
@@ -41,25 +47,26 @@
          
     def makeDropTarget(self):
         def ddr(widget, drag_context, x, y, selection_data, info, timestamp):
-            if selection_data.type != 'text/uri-list':
+            if selection_data.get_data_type().name() != 'text/uri-list':
                 raise ValueError("unknown DnD selection type %r" %
-                                 selection_data.type)
-            self.resourceObservable(URIRef(selection_data.data.strip()))
+                                 selection_data.get_data_type())
+            self.resourceObservable(URIRef(selection_data.get_data().strip()))
         
-        self.currentLink.drag_dest_set(flags=gtk.DEST_DEFAULT_ALL,
-                            targets=[('text/uri-list', 0, 0)],
-                            actions=gtk.gdk.ACTION_LINK  | gtk.gdk.ACTION_COPY)
+        self.currentLink.drag_dest_set(
+            flags=Gtk.DestDefaults.ALL,
+            targets=[Gtk.TargetEntry.new('text/uri-list', 0, 0)],
+            actions=Gdk.DragAction.LINK  | Gdk.DragAction.COPY)
         self.currentLink.connect("drag_data_received", ddr)
                 
     def makeDragSource(self):
         self.currentLink.drag_source_set(
-            start_button_mask=gtk.gdk.BUTTON1_MASK,
-            targets=[('text/uri-list', 0, 0)],
-            actions=gtk.gdk.ACTION_LINK | gtk.gdk.ACTION_COPY)
+            start_button_mask=Gdk.ModifierType.BUTTON1_MASK,
+            targets=[Gtk.TargetEntry.new(target='text/uri-list',
+                                         flags=0, info=0)],
+            actions=Gdk.DragAction.LINK  | Gdk.DragAction.COPY)
 
         def source_drag_data_get(btn, context, selection_data, info, time):
-            selection_data.set(selection_data.target, 8,
-                               self.resourceObservable())
+            selection_data.set_uris([self.resourceObservable()])
 
         self.currentLink.connect("drag_data_get", source_drag_data_get)
 
--- a/light9/gtkpyconsole.py	Sun Jun 01 10:39:17 2014 +0000
+++ b/light9/gtkpyconsole.py	Sun Jun 01 20:35:38 2014 +0000
@@ -1,5 +1,7 @@
 from lib.ipython_view import IPythonView
-import pango, gtk
+import gi
+from gi.repository import Gtk
+from gi.repository import Pango
 
 def togglePyConsole(self, item, user_ns):
     """
@@ -13,12 +15,12 @@
     """
     if item.get_active():
         if not hasattr(self, 'pythonWindow'):
-            self.pythonWindow = gtk.Window()
-            S = gtk.ScrolledWindow()
-            S.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+            self.pythonWindow = Gtk.Window()
+            S = Gtk.ScrolledWindow()
+            S.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
             V = IPythonView(user_ns=user_ns)
-            V.modify_font(pango.FontDescription("luxi mono 8"))
-            V.set_wrap_mode(gtk.WRAP_CHAR)
+            V.modify_font(Pango.FontDescription("luxi mono 8"))
+            V.set_wrap_mode(Gtk.WrapMode.CHAR)
             S.add(V)
             self.pythonWindow.add(S)
             self.pythonWindow.show_all()
--- a/makefile	Sun Jun 01 10:39:17 2014 +0000
+++ b/makefile	Sun Jun 01 20:35:38 2014 +0000
@@ -49,7 +49,7 @@
 bin/ascoltami2: gst_packages link_to_sys_packages
 
 gst_packages:
-	sudo aptitude install python-gi gir1.2-gst-plugins-base-1.0 libgirepository-1.0-1 gir1.2-gstreamer-1.0 gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-pulseaudio
+	sudo aptitude install python-gi gir1.2-gst-plugins-base-1.0 libgirepository-1.0-1 gir1.2-gstreamer-1.0 gstreamer1.0-tools gstreamer1.0-plugins-good gstreamer1.0-pulseaudio gir1.2-goocanvas-2.0-9
 
 packages:
 	sudo aptitude install coffeescript freemind normalize-audio audacity python-pygoocanvas