Changeset - 52f049d85f96
[Not reviewed]
default
0 2 0
Drew Perttula - 11 years ago 2014-06-03 05:09:41
drewp@bigasterisk.com
less CC crashing. curve points are stored in their own n3 files. fix curve row height edge cases.
Ignore-this: 7bd8e0c82d4106d53c24d67b981baf60
2 files changed with 59 insertions and 25 deletions:
0 comments (0 inline, 0 general)
light9/curvecalc/curve.py
Show inline comments
 
@@ -29,24 +29,27 @@ class Curve(object):
 
        doc = "Whether to currently send levels (boolean, obviously)"
 
        def fget(self):
 
            return self._muted
 
        def fset(self, val):
 
            self._muted = val
 
            dispatcher.send('mute changed', sender=self)
 
        return locals()
 
    muted = property(**muted())
 

	
 
    def toggleMute(self):
 
        self.muted = not self.muted
 

	
 
    def curvePointsContext(self):
 
        return self.uri
 

	
 
    def load(self,filename):
 
        self.points[:]=[]
 
        for line in file(filename):
 
            x, y = line.split()
 
            self.points.append((float(x), ast.literal_eval(y)))
 
        self.points.sort()
 
        dispatcher.send("points changed",sender=self)
 

	
 
    def set_from_string(self, pts):
 
        self.points[:] = []
 
        vals = pts.split()
 
        pairs = zip(vals[0::2], vals[1::2])
 
@@ -218,61 +221,69 @@ class Curveset(object):
 
        dispatcher.send("clear_curves")
 
        self.curves.clear()
 
        self.curveName.clear()
 
        self.sliderCurve.clear()
 
        self.sliderNum.clear()
 
        self.markers = Markers(uri=None, pointsStorage='file')
 
        
 
        self.currentSong = self.graph.value(self.session, L9['currentSong'])
 
        if self.currentSong is None:
 
            return
 

	
 
        for uri in sorted(self.graph.objects(self.currentSong, L9['curve'])):
 
            pts = self.graph.value(uri, L9['points'])
 
            c = Curve(uri, pointsStorage='file' if pts is None else 'graph')
 
            if pts is not None:
 
                c.set_from_string(pts)
 
            else:
 
                diskPts = self.graph.value(uri, L9['pointsFile'])
 
                c.load(os.path.join(showconfig.curvesDir(), diskPts))
 

	
 
            curvename = self.graph.label(uri)
 
            if not curvename:
 
                raise ValueError("curve %r has no label" % uri)
 
            self.add_curve(curvename, c)
 
            try:
 
                self.loadCurve(uri)
 
            except Exception as e:
 
                log.error("loading %s failed: %s", uri, e)
 

	
 
        basename = os.path.join(
 
            showconfig.curvesDir(),
 
            showconfig.songFilenameFromURI(self.currentSong))
 
        try:
 
            self.markers.load("%s.markers" % basename)
 
        except IOError:
 
            print "no marker file found"
 
            
 
    def loadCurve(self, uri):
 
        pts = self.graph.value(uri, L9['points'])
 
        c = Curve(uri, pointsStorage='file' if pts is None else 'graph')
 
        if pts is not None:
 
            c.set_from_string(pts)
 
        else:
 
            diskPts = self.graph.value(uri, L9['pointsFile'])
 
            if diskPts is not None:
 
                c.load(os.path.join(showconfig.curvesDir(), diskPts))
 
            else:
 
                log.warn("curve %s has no points", c.uri)
 

	
 
        curvename = self.graph.label(uri)
 
        if not curvename:
 
            raise ValueError("curve %r has no label" % uri)
 
        self.add_curve(curvename, c)
 
            
 
    def save(self):
 
        """writes a file for each curve with a name
 
        like basename-curvename, or saves them to the rdf graph"""
 
        basename=os.path.join(
 
            showconfig.curvesDir(),
 
            showconfig.songFilenameFromURI(self.currentSong))
 

	
 
        patches = []
 
        for label, curve in self.curves.items():
 
            if curve.pointsStorage == 'file':
 
                log.warn("not saving file curves anymore- skipping %s" % label)
 
                #cur.save("%s-%s" % (basename,name))
 
            elif curve.pointsStorage == 'graph':
 
                ctx = self.currentSong
 
                patches.append(self.graph.getObjectPatch(
 
                    ctx,
 
                    curve.curvePointsContext(),
 
                    subject=curve.uri,
 
                    predicate=L9['points'],
 
                    newObject=Literal(curve.points_as_string())))
 
            else:
 
                raise NotImplementedError(curve.pointsStorage)
 

	
 
        self.markers.save("%s.markers" % basename)
 
        # this will cause reloads that will clear our curve list
 
        for p in patches:
 
            self.graph.patch(p)
 

	
 
    def sorter(self, name):
 
@@ -311,34 +322,38 @@ class Curveset(object):
 

	
 
    def new_curve(self, name, renameIfExisting=True):
 
        if isinstance(name, Literal):
 
            name = str(name)
 
        if name=="":
 
            print "no name given"
 
            return
 
        if not renameIfExisting and name in self.curves:
 
            return
 
        while name in self.curves:
 
           name=name+"-1"
 

	
 
        uri = self.currentSong + ('/curve/c-%f' % time.time())
 
        uri = self.graph.sequentialUri(self.currentSong + '/curve/c-')
 
        c = Curve(uri)
 
        s, e = self.get_time_range()
 
        c.points.extend([(s, 0), (e, 0)])
 
        ctx = self.currentSong
 
        self.graph.patch(Patch(addQuads=[
 
            (self.currentSong, L9['curve'], uri, ctx),
 
            (uri, RDF.type, L9['Curve'], ctx),
 
            (uri, RDFS.label, Literal(name), ctx),
 
            (uri, L9['points'], Literal(c.points_as_string()), ctx),
 
            ]))
 
        print "pts to", c.curvePointsContext()
 
        self.graph.patch(Patch(addQuads=[
 
            (uri, L9['points'], Literal(c.points_as_string()),
 
             c.curvePointsContext()),
 
            ]))
 

	
 
    def hw_slider_in(self, num, value):
 
        try:
 
            curve = self.curves[self.sliderCurve[num]]
 
        except KeyError:
 
            return
 

	
 
        now = time.time()
 
        if now < self.sliderIgnoreInputUntil.get(num):
 
            return
 
        # don't make points too fast. This is the minimum spacing
light9/curvecalc/curveview.py
Show inline comments
 
@@ -664,26 +664,35 @@ class Curveview(object):
 
                (ht - marginBottom) - p[1] * (ht - (marginBottom + marginTop)))
 

	
 
    def world_from_screen(self,x,y):
 
        z, ht, marginBottom, marginTop = self._coords()
 
        return (x / self.canvas.props.x2 * (z.end - z.start) + z.start,
 
                ((ht - marginBottom) - y) / (ht - (marginBottom + marginTop)))
 

	
 
    def input_time(self, val, forceUpdate=False):
 
        if self._time == val:
 
            return
 
        self.update_time_bar(val)
 
        
 
    def alive(self):
 
        # Some handlers still run after a view is destroyed, which
 
        # leads to crashes in somewhere like
 
        # goocanvas_add_item. Workaround is to disable certain methods
 
        # when the widget is gone. Correct solution would be to stop
 
        # and free those handlers when the widget is gone.
 
        return self.canvas.is_visible()
 
        
 
    def update_time_bar(self, t):
 

	
 
        if not self.alive():
 
            return
 
        if not getattr(self, 'timelineLine', None):
 
            self.timelineGroup = GooCanvas.CanvasGroup(
 
                parent=self.canvas.get_root_item())
 
            self.timelineLine = polyline_new_line(
 
                parent=self.timelineGroup,
 
                points=Points([(0,0), (0,0)]),
 
                line_width=2, stroke_color='red')
 

	
 
        try:
 
            pts = [self.screen_from_world((t, 0)),
 
                   self.screen_from_world((t, 1))]
 
        except ZeroDivisionError:
 
@@ -699,31 +708,35 @@ class Curveview(object):
 
                self.create_oval(pos[0] - 8, pos[1] - 8,
 
                                 pos[0] + 8, pos[1] + 8,
 
                                 outline='#800000',
 
                                 tags=('knob',))
 
                dispatcher.send("knob out", value=prevKey[1], curve=self.curve)
 

	
 
    def update_curve(self, *args):
 
        if not getattr(self, '_pending_update', False):
 
            self._pending_update = True
 
            reactor.callLater(.01, self._update_curve)
 
        
 
    def _update_curve(self):
 
        try:
 
            self._update_curve2()
 
        except Exception:
 
            log.error("in update_curve on %s", self.curve.uri)
 
            raise
 

	
 
    def _update_curve2(self):
 
        if not getattr(self, '_pending_update', False):
 
            return
 
        self._pending_update = False
 
        if not self.canvas.is_visible():
 
            # this avoids an occasional crash in something like
 
            # goocanvas_add_item when we write objects to a canvas
 
            # that's gone
 
        if not self.alive():
 
            return
 
        if not self.redrawsEnabled:
 
            print "no redrawsEnabled, skipping", self
 
            return
 

	
 
        visible_x = (self.world_from_screen(0,0)[0],
 
                     self.world_from_screen(self.canvas.props.x2, 0)[0])
 

	
 
        visible_idxs = self.curve.indices_between(visible_x[0], visible_x[1],
 
                                                  beyond=1)
 
        visible_points = [self.curve.points[i] for i in visible_idxs]
 
        
 
@@ -801,24 +814,26 @@ class Curveview(object):
 
                                    x, ht,
 
                                    x, ht - 20,
 
                                    line_width=.5,
 
                                    stroke_color='gray70')
 
        GooCanvas.CanvasText(parent=self.curveGroup,
 
                       fill_color="white",
 
                       anchor=GooCanvas.CanvasAnchorType.SOUTH,
 
                       font="ubuntu 7",
 
                       x=x+3, y=ht-20,
 
                       text=label)
 

	
 
    def _draw_line(self, visible_points, area=False):
 
        if not visible_points:
 
            return
 
        linepts=[]
 
        step=1
 
        linewidth = 1.5
 
        maxPointsToDraw = self.canvas.props.x2 / 2
 
        if len(visible_points) > maxPointsToDraw:
 
            step = int(len(visible_points) / maxPointsToDraw)
 
            linewidth = .8
 
        for p in visible_points[::step]:
 
            try:
 
                x,y = self.screen_from_world(p)
 
            except ZeroDivisionError:
 
                x = y = -100
 
@@ -1281,36 +1296,40 @@ class Curvesetview(object):
 
            if self.visibleHeight == size.height:
 
                return
 
            print "size.height is new", size.height
 
            self.visibleHeight = size.height
 
            self.setRowHeights()
 

	
 
        visibleArea = self.curvesVBox.get_parent().get_parent()
 
        visibleArea.connect('size-allocate', sizeEvent)
 

	
 
        dispatcher.connect(self.setRowHeights, "curve row focus change")
 
        
 
    def setRowHeights(self):
 
        focusHeight = 100
 
        nRows = len(self.allCurveRows)
 
        if not nRows:
 
            return
 
        anyFocus = any(r.isFocus() for r in self.allCurveRows)
 

	
 
        evenHeight = max(14, self.visibleHeight // nRows) - 3
 
        if anyFocus:
 
            h = max(14, (self.visibleHeight - focusHeight) // (nRows - 1)) - 3
 
            focusHeight = max(100, evenHeight)
 
            if nRows > 1:
 
                otherHeight = max(14,
 
                                  (self.visibleHeight - focusHeight) //
 
                                  (nRows - 1)) - 3
 
        else:
 
            h = max(14, self.visibleHeight // nRows) - 3
 
            otherHeight = evenHeight
 
        for row in self.allCurveRows:
 
            row.setHeight(100 if row.isFocus() else h)
 
            row.setHeight(focusHeight if row.isFocus() else otherHeight)
 
            
 
    def row(self, name):
 
        if isinstance(name, Literal):
 
            name = str(name)
 
        matches = [r for r in self.allCurveRows if r.name == name]
 
        if not matches:
 
            raise ValueError("no curveRow named %r. only %s" %
 
                             (name, [r.name for r in self.allCurveRows]))
 
        return matches[0]
 

	
 
    def goLive(self):
 
        """for startup performance, none of the curves redraw
0 comments (0 inline, 0 general)