Changeset - 603383733d7c
[Not reviewed]
default
0 1 0
drewp@bigasterisk.com - 13 years ago 2012-06-18 00:42:48
drewp@bigasterisk.com
default to collapsed curves (with a display bug)
Ignore-this: 4f556f9781ea3a9406d4c219896f571b
1 file changed with 4 insertions and 0 deletions:
0 comments (0 inline, 0 general)
light9/curvecalc/curveview.py
Show inline comments
 
@@ -804,367 +804,371 @@ class Curveview(object):
 

	
 
            if worldp[1] == 0:
 
                rad += 3
 
                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))
 
            #self.tag_bind('handle%d' % i, "<Key-d>",
 
            #              lambda ev, i=i: self.remove_point_idx(i))
 
                      
 
            self.dots[i]=dot
 

	
 
        self.highlight_selected_dots()
 

	
 
    def find_index_near(self,x,y):
 
        tags = self.gettags(self.find_closest(x, y))
 
        try:
 
            handletags = [t for t in tags if t.startswith('handle')]
 
            return int(handletags[0][6:])
 
        except IndexError:
 
            raise ValueError("no point found")
 
        
 
    def new_point_at_mouse(self, ev):
 
        p = self.world_from_screen(ev.x,ev.y)
 
        x = p[0]
 
        y = self.curve.eval(x)
 
        self.add_point((x, y))
 

	
 
    def add_points(self, pts):
 
        idxs = [self.curve.insert_pt(p) for p in pts]
 
        self.update_curve()
 
        self.select_indices(idxs)
 
        
 
    def add_point(self, p):
 
        self.add_points([p])
 

	
 
    def add_marker(self, p):
 
        self.markers.insert_pt(p)
 
        self.update_curve()
 
        
 
    def remove_point_idx(self, *idxs):
 
        idxs = list(idxs)
 
        while idxs:
 
            i = idxs.pop()
 

	
 
            self.curve.points.pop(i)
 
            newsel = []
 
            newidxs = []
 
            for si in range(len(self.selected_points)):
 
                sp = self.selected_points[si]
 
                if sp == i:
 
                    continue
 
                if sp > i:
 
                    sp -= 1
 
                newsel.append(sp)
 
            for ii in range(len(idxs)):
 
                if ii > i:
 
                    ii -= 1
 
                newidxs.append(idxs[ii])
 

	
 
            self.select_indices(newsel)
 
            idxs[:] = newidxs
 
            
 
        self.update_curve()
 

	
 
    def highlight_selected_dots(self):
 
        if not self.redrawsEnabled:
 
            return
 

	
 
        for i,d in self.dots.items():
 
            if i in self.selected_points:
 
                d.set_property('fill_color', 'red')
 
            else:
 
                d.set_property('fill_color', 'blue')
 
        
 
    def dotpress(self, r1, r2, ev, dotidx):
 
        self.print_state("dotpress")
 
        if dotidx not in self.selected_points:
 
            self.select_indices([dotidx])
 

	
 
        self.last_mouse_world = self.world_from_screen(ev.x, ev.y)
 
        self.dragging_dots = True
 

	
 
    def select_between(self,start,end):
 
        if start > end:
 
            start, end = end, start
 
        self.select_indices(self.curve.indices_between(start,end))
 

	
 
    def onEnter(self, widget, event):
 
        self.entered = True
 

	
 
    def onLeave(self, widget, event):
 
        self.entered = False
 

	
 
    def onMotion(self, widget, event):
 
        self.lastMouseX = event.x
 

	
 
        if event.state & gtk.gdk.SHIFT_MASK and 1: # and B1
 
            self.sketch_motion(event)
 
            return
 

	
 
        self.select_motion(event)
 
        
 
        if not self.dragging_dots:
 
            return
 
        if not event.state & 256:
 
            return # not lmb-down
 
        cp = self.curve.points
 
        moved=0
 

	
 
        cur = self.world_from_screen(event.x, event.y)
 
        if self.last_mouse_world:
 
            delta = (cur[0] - self.last_mouse_world[0],
 
                     cur[1] - self.last_mouse_world[1])
 
        else:
 
            delta = 0,0
 
        self.last_mouse_world = cur
 
        
 
        for idx in self.selected_points:
 

	
 
            newp = [cp[idx][0] + delta[0], cp[idx][1] + delta[1]]
 
            
 
            newp[1] = max(0,min(1,newp[1]))
 
            
 
            if idx>0 and newp[0] <= cp[idx-1][0]:
 
                continue
 
            if idx<len(cp)-1 and newp[0] >= cp[idx+1][0]:
 
                continue
 
            moved=1
 
            cp[idx] = tuple(newp)
 
        if moved:
 
            self.update_curve()
 

	
 
    def unselect(self):
 
        self.select_indices([])
 

	
 
    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")
 

	
 
        if event.state & gtk.gdk.SHIFT_MASK: # relese-B1
 
            self.sketch_release(event)
 
            return
 

	
 
        self.select_release(event)
 
 
 
        if not self.dragging_dots:
 
            return
 
        self.last_mouse_world = None
 
        self.dragging_dots = False
 

	
 
class CurveRow(object):
 
    """
 
    one of the repeating curve rows (including widgets on the left)
 

	
 
    i wish these were in a list-style TreeView so i could set_reorderable on it
 

	
 
    please pack self.box
 
    """
 
    def __init__(self, name, curve, markers, slider, knobEnabled, zoomControl):
 
        self.name = name
 
        self.box = gtk.VBox()
 
        self.box.set_border_width(1)
 

	
 
        self.cols = gtk.HBox()
 
        self.box.add(self.cols)
 
        
 
        controls = gtk.Frame()
 
        controls.set_size_request(115, -1)
 
        controls.set_shadow_type(gtk.SHADOW_OUT)
 
        self.cols.pack_start(controls, expand=False)
 
        self.setupControls(controls, name, curve, slider)
 

	
 
        self.curveView = Curveview(curve, markers, knobEnabled=knobEnabled,
 
                                   isMusic=name in ['music', 'smooth_music'],
 
                                   zoomControl=zoomControl)
 
        
 
        self.initCurveView()
 
        dispatcher.connect(self.rebuild, "all curves rebuild")
 

	
 
        # incomplete: this makes the row start with a small size
 
        # request, but doesn't update the row widgets
 
        self.collapsed.props.active = True
 

	
 
    def rebuild(self):
 
        self.curveView.rebuild()
 
        self.initCurveView()
 
        self.update_ui_to_collapsed_state()
 

	
 
    def initCurveView(self):
 
        self.curveView.widget.show()
 
        self.curveView.widget.set_size_request(-1, 100)
 
        self.cols.pack_start(self.curveView.widget, expand=True)       
 
        
 
    def setupControls(self, controls, name, curve, slider):
 
        box = gtk.VBox()
 
        controls.add(box)
 
        
 
        txt = "curve '%s'" % name
 
        if len(name) > 7:
 
            txt = name
 
        curve_name_label = gtk.Label(txt)
 
        box.pack_start(curve_name_label)
 

	
 
        bools = gtk.HBox()
 
        box.pack_start(bools)
 
        self.collapsed = gtk.CheckButton("C")
 
        bools.pack_start(self.collapsed)
 
        self.collapsed.connect("toggled", self.update_ui_to_collapsed_state)
 
        self.hideWhenCollapsed = [bools]
 
        self.muted = gtk.CheckButton("M")
 
        
 
        bools.pack_start(self.muted)
 
        self.muted.connect("toggled", self.sync_mute_to_curve)
 
        dispatcher.connect(self.mute_changed, 'mute changed', sender=curve)
 

	
 
        self.sliderLabel = None
 
        if slider is not None:
 
            # slider should have a checkbutton, defaults to off for
 
            # music tracks
 
            self.sliderLabel = gtk.Label("Slider %s" % slider)
 
            box.pack_start(self.sliderLabel)
 

	
 
        # widgets that need recoloring when we tint the row:
 
        #self.widgets = [leftside, self.collapsed, self.muted,
 
        #                curve_name_label, self]
 
        #if self.sliderLabel:
 
        #    self.widgets.append(self.sliderLabel)
 

	
 
    def onDelete(self):
 
        self.curveView.onDelete()
 
        
 
    def update_ui_to_collapsed_state(self, *args):
 
        if self.collapsed.get_active():
 
            self.curveView.widget.set_size_request(-1, 25)
 
            [w.hide() for w in self.hideWhenCollapsed]
 
        else:
 
            self.curveView.widget.set_size_request(-1, 100)
 
            [w.show() for w in self.hideWhenCollapsed]
 

	
 
    def sync_mute_to_curve(self, *args):
 
        """send value from CheckButton to the master attribute inside Curve"""
 
        new_mute = self.muted.get_active()
 
        self.curveView.curve.muted = new_mute
 

	
 
    def update_mute_look(self):
 
        """set colors on the widgets in the row according to self.muted.get()"""
 
        # not yet ported for gtk
 
        return
 
        if self.curveView.curve.muted:
 
            new_bg = 'grey20'
 
        else:
 
            new_bg = 'normal'
 

	
 
        for widget in self.widgets:
 
            widget['bg'] = new_bg
 

	
 
    def mute_changed(self):
 
        """call this if curve.muted changed"""
 
        self.muted.set_active(self.curveView.curve.muted)
 
        #self.update_mute_look()
 

	
 

	
 
class Curvesetview(object):
 
    """
 
    
 
    """
 
    def __init__(self, curvesVBox, zoomControlBox, curveset):
 
        self.live = True
 
        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()
 

	
 
        for c in curveset.curveNamesInOrder():
 
            self.add_curve(c) 
 

	
 
        dispatcher.connect(self.add_curve, "add_curve", sender=self.curveset)
 
        
 
        self.newcurvename = gtk.EntryBuffer("", 0)
 

	
 
        eventBox = self.curvesVBox.get_parent()
 
        eventBox.connect("key-press-event", self.onKeyPress)
 
        eventBox.connect("button-press-event", self.takeFocus)
 

	
 
    def __del__(self):
 
        print "del curvesetview", id(self) 
 

	
 
    def takeFocus(self, *args):
 
        """the whole curveset's eventbox is what gets the focus, currently, so
 
        keys like 'c' can work in it"""
 
        dispatcher.send("all curves lose selection")
 
        self.curvesVBox.get_parent().grab_focus()
 

	
 
    def onKeyPress(self, widget, event):
 
        if not self.live: # workaround for old instances living past reload()
 
            return
 

	
 
        if event.string == 'c':
 
            r = self.row_under_mouse()
 
            # calling toggled() had no effect; don't know why
 
            r.collapsed.set_active(not r.collapsed.get_active())
 
 
 
    def row_under_mouse(self):
 
        x, y = self.curvesVBox.get_pointer()
 
        for r in self.allCurveRows:
 
            inRowX, inRowY = self.curvesVBox.translate_coordinates(r.box, x, y)
 
            _, _, w, h = r.box.get_allocation()
 
            if 0 <= inRowX < w and 0 <= inRowY < h:
 
                return r
 
        raise ValueError("no curveRow is under the mouse")
 

	
 
    def focus_entry(self):
 
        self.entry.focus()
 

	
 
    def new_curve(self, event):
 
        self.curveset.new_curve(self.newcurvename.get())
 
        self.newcurvename.set('')
 
        
 
    def add_curve(self, name, slider=None, knobEnabled=False):
 
        curve = self.curveset.curves[name]
 
        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)
 
        f.curveView.goLive()
 

	
 
    def row(self, name):
 
        matches = [r for r in self.allCurveRows if r.name == name]
 
        if not matches:
 
            raise ValueError("no curveRow named %r" % name)
 
        return matches[0]
 

	
 
    def goLive(self):
 
        """for startup performance, none of the curves redraw
 
        themselves until this is called once (and then they're normal)"""
 
        
 
        for cr in self.allCurveRows:
 
            cr.curveView.goLive()
 

	
 
    def onDelete(self):
 
        for r in self.allCurveRows:
 
            r.onDelete()
 

	
 
    def collapseAll(self):
 
        for r in self.allCurveRows:
 
            r.collapsed.set_active(True)
 

	
 
    def collapseNone(self):
 
        for r in self.allCurveRows:
 
            r.collapsed.set_active(False)
 

	
 
        
0 comments (0 inline, 0 general)