changeset 699:d12bc8919d6e

ported the zoom control Ignore-this: edce8350a21280aebf2a0e69cd7335ea
author Drew Perttula <drewp@bigasterisk.com>
date Sun, 10 Jun 2012 05:33:25 +0000
parents 2aac2ef23495
children d5692ab6bc2a
files bin/curvecalc light9/curvecalc/curvecalc.glade light9/curvecalc/curveview.py light9/curvecalc/zoomcontrol.py
diffstat 4 files changed, 236 insertions(+), 323 deletions(-) [+]
line wrap: on
line diff
--- a/bin/curvecalc	Sun Jun 10 04:03:00 2012 +0000
+++ b/bin/curvecalc	Sun Jun 10 05:33:25 2012 +0000
@@ -26,7 +26,6 @@
 
 import run_local
 from light9 import showconfig, prof
-from light9.curvecalc.zoomcontrol import Zoomcontrol
 from light9.curvecalc.curve import Curveset
 from light9.curvecalc import curveview 
 from light9.curvecalc.musicaccess import Music, currentlyPlayingSong
@@ -64,19 +63,26 @@
                                    )
 
         def refreshCurveView():
-            m = os.path.getmtime(curveview.__file__.replace('.pyc', '.py'))
+            mtimes = [os.path.getmtime(f) for f in [
+                'light9/curvecalc/curveview.py',
+                'light9/curvecalc/zoomcontrol.py',
+                ]]
 
-            if not hasattr(self, 'curvesetView') or self.curvesetView._mtime != m:
+            if (not hasattr(self, 'curvesetView') or
+                self.curvesetView._mtimes != mtimes):
                 print "reload curveview.py"
                 curvesVBox = wtree.get_object("curves")
+                zoomControlBox = wtree.get_object("zoomControlBox")
                 [curvesVBox.remove(c) for c in curvesVBox.get_children()]
+                [zoomControlBox.remove(c) for c in
+                 zoomControlBox.get_children()]
                 try:
                     linecache.clearcache()
                     reload(curveview)
                     # mem problem somewhere; need to hold a ref to this
                     self.curvesetView = curveview.Curvesetview(
-                        curvesVBox, curveset)
-                    self.curvesetView._mtime = m
+                        curvesVBox, zoomControlBox, curveset)
+                    self.curvesetView._mtimes = mtimes
 
                     # curvesetview must already exist, since this
                     # makes 'add_curve' signals for all the initial
@@ -97,7 +103,14 @@
         
         self.makeStatusLines(wtree.get_object("status"))
 
-        #zc = Zoomcontrol(root)
+    def onSeeCurrentTime(self, item):
+        dispatcher.send("see time")
+
+    def onSeeTimeUntilEnd(self, item):
+        dispatcher.send("see time until end")
+
+    def onZoomAll(self, item):
+        dispatcher.send("show all")
 
     def onPlayPause(self, item):
         # since the X coord in a curveview affects the handling, one
--- a/light9/curvecalc/curvecalc.glade	Sun Jun 10 04:03:00 2012 +0000
+++ b/light9/curvecalc/curvecalc.glade	Sun Jun 10 05:33:25 2012 +0000
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
-  <!-- interface-requires gtk+ 3.0 -->
+  <requires lib="gtk+" version="2.24"/>
+  <!-- interface-naming-policy toplevel-contextual -->
   <object class="GtkWindow" id="MainWindow">
     <property name="can_focus">False</property>
     <child>
@@ -13,9 +14,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">
@@ -25,9 +26,9 @@
                     <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>
                       </object>
@@ -35,9 +36,9 @@
                     <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>
                       </object>
@@ -48,9 +49,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">
@@ -60,9 +61,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>
@@ -70,9 +71,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>
@@ -80,9 +81,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>
@@ -93,9 +94,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">
@@ -104,45 +105,51 @@
                     <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_action_appearance">False</property>
+                        <property name="label" translatable="yes">See current time</property>
                         <property name="use_underline">True</property>
+                        <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="label" translatable="yes">See from current time -&gt; end (S-Esc)</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>
+                        <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="label" translatable="yes">Zoom all (C-Esc)</property>
+                        <property name="use_action_appearance">False</property>
+                        <property name="label" translatable="yes">Zoom all</property>
                         <property name="use_underline">True</property>
+                        <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>
@@ -153,9 +160,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">
@@ -164,9 +171,9 @@
                     <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>
                         <accelerator key="p" signal="activate" modifiers="GDK_CONTROL_MASK"/>
@@ -179,9 +186,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>
                 <signal name="activate" handler="onPlayPause" swapped="no"/>
@@ -191,9 +198,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 (del)</property>
                         <property name="use_underline">True</property>
                       </object>
@@ -249,6 +256,8 @@
                             <property name="invisible_char_set">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>
@@ -264,6 +273,29 @@
                       </packing>
                     </child>
                     <child>
+                      <object class="GtkVBox" id="zoomControlBox">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <child>
+                          <object class="GtkLabel" id="zoomControl">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="label" translatable="yes">[zoom control]</property>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
                       <object class="GtkScrolledWindow" id="scrolledwindow1">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
@@ -293,7 +325,7 @@
                       <packing>
                         <property name="expand">True</property>
                         <property name="fill">True</property>
-                        <property name="position">1</property>
+                        <property name="position">2</property>
                       </packing>
                     </child>
                   </object>
@@ -325,7 +357,6 @@
                       <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>
@@ -343,42 +374,6 @@
                                 <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>
-                                <child>
-                                  <placeholder/>
-                                </child>
                               </object>
                             </child>
                           </object>
@@ -397,7 +392,6 @@
                         <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>
@@ -429,6 +423,10 @@
                             <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>
+                            <property name="primary_icon_sensitive">True</property>
+                            <property name="secondary_icon_sensitive">True</property>
                           </object>
                           <packing>
                             <property name="expand">False</property>
@@ -486,24 +484,6 @@
                     <child>
                       <placeholder/>
                     </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
-                    <child>
-                      <placeholder/>
-                    </child>
                   </object>
                 </child>
                 <child type="label">
@@ -608,131 +588,6 @@
     <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	Sun Jun 10 04:03:00 2012 +0000
+++ b/light9/curvecalc/curveview.py	Sun Jun 10 05:33:25 2012 +0000
@@ -71,12 +71,12 @@
     """
     graphical curve widget only. Please pack .widget
     """
-    def __init__(self, curve, knobEnabled=False, isMusic=False, **kw):
+    def __init__(self, curve, knobEnabled=False, isMusic=False, zoomControl=None, **kw):
         """knobEnabled=True highlights the previous key and ties it to a
         hardware knob"""
-        print "new curveview" 
+        print "new curveview"
         self.widget = goocanvas.Canvas()
-        self.widget.set_property("background-color", "gray20")
+        self.widget.set_property("background-color", "black")
         self.widget.set_size_request(-1, 100)
         self.root = self.widget.get_root_item()
 
@@ -84,6 +84,7 @@
         self.curve = curve
         self.knobEnabled = knobEnabled
         self._isMusic = isMusic
+        self.zoomControl = zoomControl
         self._time = 0
         self.last_mouse_world = None
         self.entered = False # is the mouse currently over this widget
@@ -106,6 +107,7 @@
         self.widget.connect("leave-notify-event", self.onLeave)
         self.widget.connect("enter-notify-event", self.onEnter)
         self.widget.connect("motion-notify-event", self.onMotion)
+        self.widget.connect("scroll-event", self.onScroll)
         self.widget.connect("button-release-event", self.onRelease)
         
         if 0:
@@ -116,25 +118,6 @@
 
                 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"))
-
         # this binds on c-a-b1, etc
         if 0:
             self.regionzoom = RegionZoom(self, self.world_from_screen,
@@ -167,14 +150,17 @@
         user has pressed ctrl-p over a curve view, possibly this
         one. Returns the time under the mouse if we know it, or else
         None
+
+        todo: there should be a faint timecursor line under the mouse
+        so it's more obvious that we use that time for some
+        events. Rt-click should include Ctrl+P as 'play/pause from
+        here'
         """
-        print id(self), "checking", self.entered
+        # maybe self.widget.get_pointer would be ok for this? i didn't try it
         if self.entered:
             t = self.world_from_screen(self.lastMouseX, 0)[0]
-            print self.lastMouseX, t
             return t
         return None
-        #dispatcher.send("music seek", t=self.world_from_screen(ev.x,0)[0])
 
     def goLive(self):
         """this is for startup performance only, since the curves were
@@ -265,14 +251,14 @@
         return self._time
 
     def screen_from_world(self,p):
-        start,end = self.zoom
+        z = self.zoomControl
         ht = self.size.height
-        return (p[0]-start)/(end-start)*self.size.width, (ht-5)-p[1]*(ht-10)
+        return (p[0]-z.start)/(z.end-z.start)*self.size.width, (ht-5)-p[1]*(ht-10)
 
     def world_from_screen(self,x,y):
-        start,end = self.zoom
+        z = self.zoomControl
         ht = self.size.height
-        return x/self.size.width*(end-start)+start, ((ht-5)-y)/(ht-10)
+        return x/self.size.width*(z.end-z.start)+z.start, ((ht-5)-y)/(ht-10)
 
     def input_time(self, val, forceUpdate=False):
         # i tried various things to make this not update like crazy,
@@ -310,9 +296,7 @@
             return
         self.size = self.widget.get_allocation()
  
-        self.zoom = 0, 228#dispatcher.send("zoom area")[0][1]
         cp = self.curve.points
-
         visible_x = (self.world_from_screen(0,0)[0],
                      self.world_from_screen(self.size.width, 0)[0])
 
@@ -345,7 +329,7 @@
         """are we one of the music curves (which might be drawn a bit
         differently)"""
         return self._isMusic
-
+ 
     def _draw_gradient(self):
         print "no grad"
         return
@@ -408,18 +392,19 @@
                                     stroke_color='gray70')
         goocanvas.Text(parent=self.curveGroup,
                        fill_color="white",
-                       font="ubuntu 9",
+                       anchor=gtk.ANCHOR_SOUTH,
+                       font="ubuntu 7",
                        x=x+3, y=ht-20,
                        text=label)
 
     def _draw_line(self,visible_points):
         linepts=[]
         step=1
-        linewidth = 3
-        # 800? maybe this should be related to self.width
-        if len(visible_points) > 800:
-            step = int(len(visible_points) / 800)
-            linewidth = .5
+        linewidth = 1.5
+        maxPointsToDraw = self.size.width / 2
+        if len(visible_points) > maxPointsToDraw:
+            step = int(len(visible_points) / maxPointsToDraw)
+            linewidth = .8
         for p in visible_points[::step]:
             linepts.append(self.screen_from_world(p))
 
@@ -459,15 +444,15 @@
                                  )
             if worldp[1] == 0:
                 rad += 3
-                dot2 = goocanvas.Ellipse(parent=self.curveGroup,
-                                         center_x=p[0],
-                                         center_y=p[1],
-                                         radius_x=rad,
-                                         radius_y=rad,
-                                         line_width=.8,
-                                         stroke_color='darkgreen',
-                                         #tags=('curve','point', 'handle%d' % i)
-                                         )
+                goocanvas.Ellipse(parent=self.curveGroup,
+                                  center_x=p[0],
+                                  center_y=p[1],
+                                  radius_x=rad,
+                                  radius_y=rad,
+                                  line_width=2,
+                                  stroke_color='#00a000',
+                                  #tags=('curve','point', 'handle%d' % i)
+                                  )
             dot.connect("button-press-event", self.dotpress, i)
             #self.tag_bind('handle%d' % i,"<ButtonPress-1>",
             #              lambda ev,i=i: self.dotpress(ev,i))
@@ -596,6 +581,11 @@
     def unselect(self):
         self.selected_points=[]
         self.highlight_selected_dots()
+
+    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)
         
     def onRelease(self, widget, event):
         self.print_state("dotrelease")
@@ -610,8 +600,7 @@
 
     please pack self.box
     """
-    def __init__(self, name, curve, slider, knobEnabled):
-
+    def __init__(self, name, curve, slider, knobEnabled, zoomControl):
         self.box = gtk.HandleBox()
         self.box.set_border_width(1)
 
@@ -625,7 +614,8 @@
         self.setupControls(controls, name, curve, slider)
 
         self.curveView = Curveview(curve, knobEnabled=knobEnabled,
-                                   isMusic=name in ['music', 'smooth_music'])
+                                   isMusic=name in ['music', 'smooth_music'],
+                                   zoomControl=zoomControl)
         cols.pack_start(self.curveView.widget, expand=True)
         
     def setupControls(self, controls, name, curve, slider):
@@ -711,14 +701,21 @@
     """
     
     """
-    def __init__(self, curvesVBox, curveset):
+    def __init__(self, curvesVBox, zoomControlBox, curveset):
         self.curvesVBox = curvesVBox
         self.curveset = curveset
         self.allCurveRows = set()
 
+        import light9.curvecalc.zoomcontrol
+        reload(light9.curvecalc.zoomcontrol)
+        self.zoomControl = light9.curvecalc.zoomcontrol.ZoomControl()
+        zoomControlBox.add(self.zoomControl.widget)
+        self.zoomControl.widget.show_all()
+
         dispatcher.connect(self.add_curve, "add_curve", sender=self.curveset)
         
         self.newcurvename = gtk.EntryBuffer("", 0)
+        
         return
 
         entry = tk.Entry(f, textvariable=self.newcurvename)
@@ -728,6 +725,7 @@
         
         
         dispatcher.connect(self.focus_entry, "focus new curve")
+
     def focus_entry(self):
         self.entry.focus()
 
@@ -737,7 +735,7 @@
         
     def add_curve(self, name, slider=None, knobEnabled=False):
         curve = self.curveset.curves[name]
-        f = CurveRow(name, curve, slider, knobEnabled)
+        f = CurveRow(name, curve, slider, knobEnabled, self.zoomControl)
         self.curvesVBox.pack_end(f.box)
         f.box.show_all()
         self.allCurveRows.add(f)
--- a/light9/curvecalc/zoomcontrol.py	Sun Jun 10 04:03:00 2012 +0000
+++ b/light9/curvecalc/zoomcontrol.py	Sun Jun 10 05:33:25 2012 +0000
@@ -1,9 +1,12 @@
 from __future__ import division
-import Tkinter as tk
+import gtk, goocanvas
 import louie as dispatcher
 from light9.curvecalc import cursors 
 
-class Zoomcontrol(object,tk.Canvas):
+class ZoomControl(object):
+    """
+    please pack .widget
+    """
 
     mintime = 0
 
@@ -48,51 +51,57 @@
         return locals()
     offset = property(**offset())
 
-    def __init__(self,master,**kw):
-        self.maxtime=370
+    def __init__(self, **kw):
+        self.widget = goocanvas.Canvas(bounds_padding=5)
+        self.widget.set_property("background-color", "gray60")
+        self.widget.set_size_request(-1, 30)
+
+        endtimes = dispatcher.send("get max time")
+        if endtimes:
+            self.maxtime = endtimes[0][1]
+        else:
+            self.maxtime = 0
+
         self.start=0
         self.end=20
-        tk.Canvas.__init__(self,master,width=250,height=30,
-                           relief='raised',bd=1,bg='gray60',**kw)
-        self.leftbrack = self.create_line(0,0,0,0,0,0,0,0,width=5)
-        self.rightbrack = self.create_line(0,0,0,0,0,0,0,0,width=5)
-        self.shade = self.create_rectangle(0,0,0,0,fill='gray70',outline=None)
-        self.time = self.create_line(0,0,0,0,fill='red',width=2)
-        self.redrawzoom()
-        self.bind("<Configure>",self.redrawzoom)
 
-        if 0:
-            # works, but you have to stay in the widget while you drag
-            self.bind("<ButtonPress-1>",self.press)
-            self.tag_bind(self.leftbrack,"<B1-Motion>",
-                          lambda ev: self.adjust(ev,'start'))
-            self.tag_bind(self.rightbrack,"<B1-Motion>",
-                          lambda ev: self.adjust(ev,'end'))
-            self.tag_bind(self.shade,"<B1-Motion>",
-                          lambda ev: self.adjust(ev,'offset'))
-        else:
-            # works better
-            # bind to buttonpress wasnt working, but Enter is good enough
-            self.tag_bind(self.leftbrack,"<Enter>",
-                          lambda ev: self.press(ev,'start'))
-            self.tag_bind(self.shade,"<Enter>",
-                          lambda ev: self.press(ev,'offset'))
-            self.tag_bind(self.rightbrack,"<Enter>",
-                          lambda ev: self.press(ev,'end'))
-            self.bind("<B1-Motion>",self.adjust)
-            self.bind("<ButtonRelease-1>",self.release)
+        self.root = self.widget.get_root_item()
+        self.leftbrack = goocanvas.Polyline(parent=self.root,
+                                            line_width=5, stroke_color='black')
+        self.rightbrack = goocanvas.Polyline(parent=self.root,
+                                             line_width=5, stroke_color='black')
+        self.shade = goocanvas.Rect(parent=self.root,
+                                    fill_color='gray70',
+                                    line_width=.5)
+        self.time = goocanvas.Polyline(parent=self.root,
+                                       line_width=2,
+                                       stroke_color='red')
+        self.redrawzoom()
+        self.widget.connect("size-allocate", self.redrawzoom)
+
+        self.widget.connect("motion-notify-event", self.adjust)
+        self.widget.connect("button-release-event", self.release)
+        self.leftbrack.connect("button-press-event",
+                               lambda i, t, ev: self.press(ev, 'start'))
+        self.rightbrack.connect("button-press-event",
+                                lambda i, t, ev: self.press(ev, 'end'))
+        self.shade.connect("button-press-event",
+                           lambda i, t, ev: self.press(ev, 'offset'))
         
-        dispatcher.connect(lambda: (self.start,self.end),"zoom area",weak=0)
         dispatcher.connect(self.input_time,"input time")
-        dispatcher.connect(lambda maxtime: (setattr(self,'maxtime',maxtime),
-                                            self.redrawzoom()),
-                           "max time",weak=0)
+        dispatcher.connect(self.max_time, "max time")
         dispatcher.connect(self.zoom_about_mouse, "zoom about mouse")
         dispatcher.connect(self.see_time, "see time")
         dispatcher.connect(self.see_time_until_end, "see time until end")
         dispatcher.connect(self.show_all, "show all")
         dispatcher.connect(self.zoom_to_range, "zoom to range")
         self.created=1
+        self.lastTime = 0
+
+    def max_time(self, maxtime):
+        self.maxtime = maxtime
+        self.redrawzoom()
+    
     def zoom_to_range(self,start,end):
         self.start = start
         self.end = end
@@ -108,7 +117,10 @@
         self.end = t + factor*(self.end-t)
         self.redrawzoom()
 
-    def see_time(self, t):
+    def see_time(self, t=None):
+        """defaults to current time"""
+        if t is None:
+            t = self.lastTime
         vis_seconds = self.end - self.start
         margin = vis_seconds * .1
         if t < self.start or t > (self.end - vis_seconds * .3):
@@ -116,24 +128,32 @@
 
         self.redrawzoom()
 
-    def see_time_until_end(self, t):
+    def see_time_until_end(self, t=None):
+        """defaults to current time"""
+        if t is None:
+            t = self.lastTime
         self.start = t - 2
         self.end = self.maxtime
 
         self.redrawzoom()
             
     def input_time(self,val):
-        t=val
-        x=self.can_for_t(t)
-        self.coords(self.time,x,0,x,self.winfo_height())
+        self.lastTime = val
+        x = self.can_for_t(self.lastTime)
+        self.time.set_property("points",
+                               goocanvas.Points([(x, 0),
+                                                 (x, self.size.height)]))
+        
     def press(self,ev,attr):
         self.adjustingattr = attr
         
-    def release(self,ev):
-        if hasattr(self,'adjustingattr'): del self.adjustingattr
-        if hasattr(self,'lastx'): del self.lastx
+    def release(self, widget, ev):
+        if hasattr(self,'adjustingattr'):
+            del self.adjustingattr
+        if hasattr(self,'lastx'):
+            del self.lastx
         
-    def adjust(self,ev,attr=None):
+    def adjust(self, widget, ev):
 
         if not hasattr(self,'adjustingattr'):
             return
@@ -147,36 +167,63 @@
         self.redrawzoom()
 
     def can_for_t(self,t):
-        return (t-self.mintime)/(self.maxtime-self.mintime)*(self.winfo_width()-30)+20
+        a, b = self.mintime, self.maxtime
+        return (t - a) / (b - a) * (self.size.width - 30) + 20
     def t_for_can(self,x):
-        return (x-20)/(self.winfo_width()-30)*(self.maxtime-self.mintime)+self.mintime
+        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()
         dispatcher.send("zoom changed")
-        if not hasattr(self,'created'): return
-        y1,y2=3,self.winfo_height()-3
+        if not hasattr(self,'created'):
+            return
+        y1, y2 = 3, self.size.height - 3
         lip = 6
         scan = self.can_for_t(self.start)
         ecan = self.can_for_t(self.end)
-        self.coords(self.leftbrack,scan+lip,y1,scan,y1,scan,y2,scan+lip,y2)
-        self.coords(self.rightbrack,ecan-lip,y1,ecan,y1,ecan,y2,ecan-lip,y2)
-        self.coords(self.shade,scan+5,y1+lip,ecan-5,y2-lip)
+
+        self.leftbrack.set_property("points", goocanvas.Points([
+            (scan + lip, y1),
+            (scan, y1),
+            (scan, y2),
+            (scan + lip, y2)]))
+        self.rightbrack.set_property("points", goocanvas.Points([
+            (ecan - lip, y1),
+            (ecan, y1),
+            (ecan, y2),
+            (ecan - lip, y2)]))
+        self.shade.set_properties(
+            x=scan + 5,
+            y=y1 + lip,
+            width=max(0, ecan - 5 - (scan + 5)),
+            height=max(0, y2 - lip - (y1 + lip)))
+
         self.redrawTics()
         
     def redrawTics(self):
-        self.delete("tics")
-        lastx=-1000
+        if hasattr(self, 'ticsGroup'):
+            self.ticsGroup.remove()
+        self.ticsGroup = goocanvas.Group(parent=self.root)
+
+        lastx =- 1000
+
         for t in range(0,int(self.maxtime)):
             x = self.can_for_t(t)
-            if 0 < x < self.winfo_width() and x-lastx>30:
-                txt=str(t)
-                if lastx==-1000:
-                    txt=txt+"sec"
-                self.create_line(x,0,x,15,
-                                 tags=('tics',))
-                self.create_text(x, self.winfo_height()-1, anchor='s',
-                                 text=txt, tags=('tics',), font='arial 7')
+            if 0 < x < self.size.width and x - lastx > 30:
+                txt = str(t)
+                if lastx == -1000:
+                    txt = txt + "sec"
+                goocanvas.Polyline(parent=self.ticsGroup,
+                                   points=goocanvas.Points([(x, 0), (x, 15)]),
+                                   line_width=.8,
+                                   stroke_color='black')
+                goocanvas.Text(parent=self.ticsGroup,
+                               x=x, y=self.size.height-1,
+                               anchor=gtk.ANCHOR_SOUTH,
+                               text=txt,
+                               font='ubuntu 7')
                 lastx = x