changeset 730:d9441146f279

new time marker system. fixed disappearing time cursor Ignore-this: 987b1462febca09f29f5d738d696161f
author Drew Perttula <drewp@bigasterisk.com>
date Thu, 14 Jun 2012 07:54:37 +0000
parents b5efddd80dad
children 9cd3a28d6929
files light9/curvecalc/curve.py light9/curvecalc/curvecalc.glade light9/curvecalc/curveview.py
diffstat 3 files changed, 69 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/light9/curvecalc/curve.py	Thu Jun 14 06:38:30 2012 +0000
+++ b/light9/curvecalc/curve.py	Thu Jun 14 07:54:37 2012 +0000
@@ -1,5 +1,5 @@
 from __future__ import division
-import glob, time, logging
+import glob, time, logging, ast
 from bisect import bisect_left,bisect
 import louie as dispatcher
 
@@ -12,13 +12,12 @@
 
 class Curve(object):
     """curve does not know its name. see Curveset"""
-    points = None # x-sorted list of (x,y)
     def __init__(self):
-        self.points = []
+        self.points = [] # x-sorted list of (x,y)
         self._muted = False
 
     def __repr__(self):
-        return "<Curve (%s points)>" % len(self.points)
+        return "<%s (%s points)>" % (self.__class__.__name__, len(self.points))
 
     def muted():
         doc = "Whether to currently send levels (boolean, obviously)"
@@ -36,7 +35,8 @@
     def load(self,filename):
         self.points[:]=[]
         for line in file(filename):
-            self.points.append(tuple([float(a) for a in line.split()]))
+            x, y = line.split()
+            self.points.append((float(x), ast.literal_eval(y)))
         self.points.sort()
         dispatcher.send("points changed",sender=self)
 
@@ -46,7 +46,7 @@
             return
         f = file(filename,'w')
         for p in self.points:
-            f.write("%s %s\n" % p)
+            f.write("%s %r\n" % p)
         f.close()
 
     def eval(self, t, allow_muting=True):
@@ -66,9 +66,9 @@
         return y
     __call__=eval
 
-    def insert_pt(self,new_pt):
+    def insert_pt(self, new_pt):
         """returns index of new point"""
-        i = bisect(self.points,(new_pt[0],None))
+        i = bisect(self.points, (new_pt[0],None))
         self.points.insert(i,new_pt)
         return i
 
@@ -93,7 +93,12 @@
         if leftidx < 0:
             return None
         return leftidx
-        
+
+class Markers(Curve):
+    """Marker is like a point but the y value is a string"""
+    def eval(self):
+        raise NotImplementedError()
+    
 
 def slope(p1,p2):
     if p2[0] == p1[0]:
@@ -153,12 +158,19 @@
             c.load(filename)
             curvename = curvename.replace('-','_')
             self.add_curve(curvename,c)
+
+        self.markers = Markers()
+        try:
+            self.markers.load("%s.markers" % basename)
+        except IOError:
+            print "no marker file found"
             
     def save(self,basename):
         """writes a file for each curve with a name
         like basename-curvename"""
         for name,cur in self.curves.items():
             cur.save("%s-%s" % (basename,name))
+        self.markers.save("%s.markers" % basename)
 
     def curveNamesInOrder(self):
         return sorted(self.curves.keys(), key=self.sorter)
--- a/light9/curvecalc/curvecalc.glade	Thu Jun 14 06:38:30 2012 +0000
+++ b/light9/curvecalc/curvecalc.glade	Thu Jun 14 07:54:37 2012 +0000
@@ -692,8 +692,8 @@
   </object>
   <object class="GtkTextBuffer" id="help">
     <property name="text">Mousewheel zoom; C-p play/pause music at mouse
-Over a curve: C to collapse; R to rebuild canvas widget
-Curve point bindings: B1 drag point; C-B1 curve add point; S-B1 sketch points; 1..5 add point at time cursor; B1 drag select points
+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">
--- a/light9/curvecalc/curveview.py	Thu Jun 14 06:38:30 2012 +0000
+++ b/light9/curvecalc/curveview.py	Thu Jun 14 07:54:37 2012 +0000
@@ -272,7 +272,7 @@
     """
     graphical curve widget only. Please pack .widget
     """
-    def __init__(self, curve, knobEnabled=False, isMusic=False,
+    def __init__(self, curve, markers, knobEnabled=False, isMusic=False,
                  zoomControl=None):
         """knobEnabled=True highlights the previous key and ties it to a
         hardware knob"""
@@ -281,6 +281,7 @@
         self.rebuild()
         
         self.curve = curve
+        self.markers = markers
         self.knobEnabled = knobEnabled
         self._isMusic = isMusic
         self.zoomControl = zoomControl
@@ -393,6 +394,8 @@
         if event.string in list('12345'):
             x = int(event.string)
             self.add_point((self.current_time(), (x - 1) / 4.0))
+        if event.string in list('qwerty'):
+            self.add_marker((self.current_time(), event.string))
 
     def onExpose(self, *args):
         if self.culled:
@@ -598,7 +601,9 @@
     def input_time(self, val, forceUpdate=False):
         if self._time == val:
             return
-        t=val
+        self.update_time_bar(val)
+        
+    def update_time_bar(self, t):
 
         if not getattr(self, 'timelineLine', None):
             self.timelineGroup = goocanvas.Group(parent=self.root)
@@ -608,8 +613,8 @@
                 line_width=2, stroke_color='red')
 
         self.timelineLine.set_property('points', goocanvas.Points([
-            self.screen_from_world((val,0)),
-            self.screen_from_world((val,1))]))
+            self.screen_from_world((t, 0)),
+            self.screen_from_world((t, 1))]))
         
         self._time = t
         if self.knobEnabled:
@@ -668,11 +673,15 @@
         #self.canvas.set_property("background-color",
         #                         "gray20" if self.curve.muted else "black")
 
+        self.update_time_bar(self._time)
         if self.size.height < 40:
             self._draw_line(visible_points, area=True)
         else:
-            self._draw_markers(visible_x)
+            self._draw_time_tics(visible_x)
             self._draw_line(visible_points)
+            self._draw_markers(
+                self.markers.points[i] for i in
+                self.markers.indices_between(visible_x[0], visible_x[1]))
 
             self.dots = {} # idx : canvas rectangle
 
@@ -686,23 +695,39 @@
         differently)"""
         return self._isMusic
 
-    def _draw_markers(self,visible_x):
-        mark = self._draw_one_marker
+    def _draw_markers(self, pts):
+        colorMap = {
+            'q':'#598522',
+            'w':'#662285',
+            'e':'#852922',
+            'r':'#85225C',
+            't':'#856B22',
+            'y':'#227085',
+            }
+        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'))
 
-        mark(0, "0")
+    def _draw_time_tics(self,visible_x):
+        tic = self._draw_one_tic
+
+        tic(0, "0")
         t1,t2=visible_x
         if t2-t1<30:
             for t in range(int(t1),int(t2)+1):
-                mark(t,str(t))
-        mark(introPad, str(introPad))
+                tic(t,str(t))
+        tic(introPad, str(introPad))
 
         endtimes = dispatcher.send("get max time")
         if endtimes:
             endtime = endtimes[0][1]
-            mark(endtime, "end %.1f"%endtime)
-            mark(endtime - postPad, "post %.1f" % (endtime - postPad))
+            tic(endtime, "end %.1f"%endtime)
+            tic(endtime - postPad, "post %.1f" % (endtime - postPad))
         
-    def _draw_one_marker(self,t,label):
+    def _draw_one_tic(self,t,label):
         x = self.screen_from_world((t,0))[0]
         ht = self.size.height
         if not 0 <= x < self.size.width:
@@ -811,6 +836,10 @@
         i = self.curve.insert_pt(p)
         self.update_curve()
         self.select_indices([i])
+
+    def add_marker(self, p):
+        self.markers.insert_pt(p)
+        self.update_curve()
         
     def remove_point_idx(self, *idxs):
         idxs = list(idxs)
@@ -935,7 +964,7 @@
 
     please pack self.box
     """
-    def __init__(self, name, curve, slider, knobEnabled, zoomControl):
+    def __init__(self, name, curve, markers, slider, knobEnabled, zoomControl):
         self.name = name
         self.box = gtk.VBox()
         self.box.set_border_width(1)
@@ -949,7 +978,7 @@
         self.cols.pack_start(controls, expand=False)
         self.setupControls(controls, name, curve, slider)
 
-        self.curveView = Curveview(curve, knobEnabled=knobEnabled,
+        self.curveView = Curveview(curve, markers, knobEnabled=knobEnabled,
                                    isMusic=name in ['music', 'smooth_music'],
                                    zoomControl=zoomControl)
         self.initCurveView()
@@ -1098,7 +1127,8 @@
         
     def add_curve(self, name, slider=None, knobEnabled=False):
         curve = self.curveset.curves[name]
-        f = CurveRow(name, curve, slider, knobEnabled, self.zoomControl)
+        f = CurveRow(name, curve, self.curveset.markers,
+                     slider, knobEnabled, self.zoomControl)
         self.curvesVBox.pack_start(f.box)
         f.box.show_all()
         self.allCurveRows.add(f)