annotate bin/curvecalc @ 711:e94989da079c

more curve editor bindings. delete signal isn't done Ignore-this: e81c81134cd87f3633821841c4ec8dac
author drewp@bigasterisk.com
date Sun, 10 Jun 2012 21:05:57 +0000
parents 10ee0756a119
children 9865cf5e07fd
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
686
a301a0039c66 buildout and rdflib updates
Drew Perttula <drewp@bigasterisk.com>
parents: 684
diff changeset
1 #!bin/python
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
2
197
ba2677823b35 zoom control and other cleanups. also reads song length now
drewp
parents: 196
diff changeset
3 """
351
a6662d61ebcd SC, KC, CC now run and seem to load and save ok. CC does not have any rdf for its data files
Drew Perttula <drewp@bigasterisk.com>
parents: 335
diff changeset
4 now launches like this:
a6662d61ebcd SC, KC, CC now run and seem to load and save ok. CC does not have any rdf for its data files
Drew Perttula <drewp@bigasterisk.com>
parents: 335
diff changeset
5 % bin/curvecalc http://light9.bigasterisk.com/show/dance2007/song1
a6662d61ebcd SC, KC, CC now run and seem to load and save ok. CC does not have any rdf for its data files
Drew Perttula <drewp@bigasterisk.com>
parents: 335
diff changeset
6
a6662d61ebcd SC, KC, CC now run and seem to load and save ok. CC does not have any rdf for its data files
Drew Perttula <drewp@bigasterisk.com>
parents: 335
diff changeset
7
a6662d61ebcd SC, KC, CC now run and seem to load and save ok. CC does not have any rdf for its data files
Drew Perttula <drewp@bigasterisk.com>
parents: 335
diff changeset
8
197
ba2677823b35 zoom control and other cleanups. also reads song length now
drewp
parents: 196
diff changeset
9 todo: curveview should preserve more objects, for speed maybe
ba2677823b35 zoom control and other cleanups. also reads song length now
drewp
parents: 196
diff changeset
10
ba2677823b35 zoom control and other cleanups. also reads song length now
drewp
parents: 196
diff changeset
11 """
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
12 from __future__ import division
694
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
13
691
62d83d456f2e curvecalc start gtk porting
drewp@bigasterisk.com
parents: 690
diff changeset
14 from twisted.internet import gtk2reactor
694
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
15 gtk2reactor.install()
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
16 from twisted.internet import reactor
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
17
700
d5692ab6bc2a fix quit and ctrl-q by using kill -9
Drew Perttula <drewp@bigasterisk.com>
parents: 699
diff changeset
18 import time, textwrap, os, optparse, urllib2, gtk, gobject, linecache, signal
689
03453848ed4c refactor musicaccess
drewp@bigasterisk.com
parents: 688
diff changeset
19 import louie as dispatcher
691
62d83d456f2e curvecalc start gtk porting
drewp@bigasterisk.com
parents: 690
diff changeset
20 from twisted.python.util import sibpath
706
16042667ab51 ui for making a new subterm
Drew Perttula <drewp@bigasterisk.com>
parents: 705
diff changeset
21 from rdflib import URIRef, Graph, Literal, RDF, RDFS
319
2193eab0650b add startup logging to curvecalc
Drew Perttula <drewp@bigasterisk.com>
parents: 296
diff changeset
22 import logging
2193eab0650b add startup logging to curvecalc
Drew Perttula <drewp@bigasterisk.com>
parents: 296
diff changeset
23 log = logging.getLogger()
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
24
210
f41004d5a507 factored out some networking, new show/ layout, curvecalc works
drewp@bigasterisk.com
parents: 205
diff changeset
25 import run_local
690
847edbfe65c8 refactor subterms
drewp@bigasterisk.com
parents: 689
diff changeset
26 from light9 import showconfig, prof
688
97b028ed0e47 curvecalc package move
drewp@bigasterisk.com
parents: 687
diff changeset
27 from light9.curvecalc.curve import Curveset
696
929ccd4ec800 live reloading of curveview.py, very nice
Drew Perttula <drewp@bigasterisk.com>
parents: 695
diff changeset
28 from light9.curvecalc import curveview
689
03453848ed4c refactor musicaccess
drewp@bigasterisk.com
parents: 688
diff changeset
29 from light9.curvecalc.musicaccess import Music, currentlyPlayingSong
264
0f112a7dd6b3 fix window positoins for subcomposer and curvecalc. now saves geometry continuously
drewp@bigasterisk.com
parents: 248
diff changeset
30 from light9.wavelength import wavelength
335
8a1ec8aca432 more rdf updates
drewp@bigasterisk.com
parents: 332
diff changeset
31 from light9.namespaces import L9
690
847edbfe65c8 refactor subterms
drewp@bigasterisk.com
parents: 689
diff changeset
32 from light9.curvecalc.subterm import read_all_subs, savekey, graphPathForSubterms
694
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
33 from light9.curvecalc.subtermview import add_one_subterm
690
847edbfe65c8 refactor subterms
drewp@bigasterisk.com
parents: 689
diff changeset
34 from light9.curvecalc.output import Output
708
10ee0756a119 new python console
Drew Perttula <drewp@bigasterisk.com>
parents: 707
diff changeset
35 from light9.gtkpyconsole import togglePyConsole
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
36
505
cbc98de2ab06 refactor curveCalc toplevel
drewp@bigasterisk.com
parents: 493
diff changeset
37 def makeGraph():
cbc98de2ab06 refactor curveCalc toplevel
drewp@bigasterisk.com
parents: 493
diff changeset
38 graphOrig = showconfig.getGraph()
cbc98de2ab06 refactor curveCalc toplevel
drewp@bigasterisk.com
parents: 493
diff changeset
39 graph = Graph() # a copy, since we're going to add subs into it
cbc98de2ab06 refactor curveCalc toplevel
drewp@bigasterisk.com
parents: 493
diff changeset
40 for s in graphOrig:
cbc98de2ab06 refactor curveCalc toplevel
drewp@bigasterisk.com
parents: 493
diff changeset
41 graph.add(s)
cbc98de2ab06 refactor curveCalc toplevel
drewp@bigasterisk.com
parents: 493
diff changeset
42 read_all_subs(graph)
cbc98de2ab06 refactor curveCalc toplevel
drewp@bigasterisk.com
parents: 493
diff changeset
43 return graph
0
45b12307c695 Initial revision
drewp
parents:
diff changeset
44
691
62d83d456f2e curvecalc start gtk porting
drewp@bigasterisk.com
parents: 690
diff changeset
45 class Main(object):
698
2aac2ef23495 time cursor, control-p over curveviews
Drew Perttula <drewp@bigasterisk.com>
parents: 697
diff changeset
46 def __init__(self, graph, opts, song, curveset, subterms, music):
701
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
47 self.graph, self.opts, self.song = graph, opts, song
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
48 self.curveset, self.subterms, self.music = curveset, subterms, music
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
49
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
50 wtree = self.wtree = gtk.Builder()
702
155c7bb9c948 window geom
Drew Perttula <drewp@bigasterisk.com>
parents: 701
diff changeset
51 wtree.add_from_file("light9/curvecalc/curvecalc.glade")
691
62d83d456f2e curvecalc start gtk porting
drewp@bigasterisk.com
parents: 690
diff changeset
52 mainwin = wtree.get_object("MainWindow")
700
d5692ab6bc2a fix quit and ctrl-q by using kill -9
Drew Perttula <drewp@bigasterisk.com>
parents: 699
diff changeset
53
d5692ab6bc2a fix quit and ctrl-q by using kill -9
Drew Perttula <drewp@bigasterisk.com>
parents: 699
diff changeset
54 mainwin.connect("destroy", self.onQuit)
691
62d83d456f2e curvecalc start gtk porting
drewp@bigasterisk.com
parents: 690
diff changeset
55 wtree.connect_signals(self)
701
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
56 gtk.rc_parse("theme/marble-ice/gtk-2.0/gtkrc")
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
57 gtk.rc_parse_string("""style "default" {font_name = "sans 7"}""")
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
58 if self.opts.reload:
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
59 self.refreshTheme()
691
62d83d456f2e curvecalc start gtk porting
drewp@bigasterisk.com
parents: 690
diff changeset
60 mainwin.show_all()
62d83d456f2e curvecalc start gtk porting
drewp@bigasterisk.com
parents: 690
diff changeset
61
694
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
62 mainwin.connect("delete-event", lambda *args: reactor.crash())
692
ccdd04f4ca7d subterm display is working
Drew Perttula <drewp@bigasterisk.com>
parents: 691
diff changeset
63 mainwin.set_title("curvecalc - %s" % graph.label(song))
702
155c7bb9c948 window geom
Drew Perttula <drewp@bigasterisk.com>
parents: 701
diff changeset
64 mainwin.parse_geometry("715x930+1080+26")
155c7bb9c948 window geom
Drew Perttula <drewp@bigasterisk.com>
parents: 701
diff changeset
65
155c7bb9c948 window geom
Drew Perttula <drewp@bigasterisk.com>
parents: 701
diff changeset
66 # this is the only one i found that would set the size right,
155c7bb9c948 window geom
Drew Perttula <drewp@bigasterisk.com>
parents: 701
diff changeset
67 # but it's a minimum size, which i don't really want
155c7bb9c948 window geom
Drew Perttula <drewp@bigasterisk.com>
parents: 701
diff changeset
68 mainwin.set_size_request(1000, 1000)
694
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
69
706
16042667ab51 ui for making a new subterm
Drew Perttula <drewp@bigasterisk.com>
parents: 705
diff changeset
70 self.add_subterms_for_song(song, curveset, subterms)
701
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
71 self.refreshCurveView()
694
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
72
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
73 self.makeStatusLines(wtree.get_object("status"))
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
74
705
ed50631cf333 new curve dialog
Drew Perttula <drewp@bigasterisk.com>
parents: 704
diff changeset
75 def onNewCurve(self, *args):
707
c4a38a247b26 cleanup. 'create' menu
Drew Perttula <drewp@bigasterisk.com>
parents: 706
diff changeset
76 dialog = self.wtree.get_object("newCurve")
705
ed50631cf333 new curve dialog
Drew Perttula <drewp@bigasterisk.com>
parents: 704
diff changeset
77 entry = self.wtree.get_object("newCurveName")
ed50631cf333 new curve dialog
Drew Perttula <drewp@bigasterisk.com>
parents: 704
diff changeset
78 # if you don't have songx, that should be the suggested name
ed50631cf333 new curve dialog
Drew Perttula <drewp@bigasterisk.com>
parents: 704
diff changeset
79 entry.set_text("")
707
c4a38a247b26 cleanup. 'create' menu
Drew Perttula <drewp@bigasterisk.com>
parents: 706
diff changeset
80 if dialog.run() == 1:
705
ed50631cf333 new curve dialog
Drew Perttula <drewp@bigasterisk.com>
parents: 704
diff changeset
81 self.curveset.new_curve(entry.get_text())
707
c4a38a247b26 cleanup. 'create' menu
Drew Perttula <drewp@bigasterisk.com>
parents: 706
diff changeset
82 dialog.hide()
705
ed50631cf333 new curve dialog
Drew Perttula <drewp@bigasterisk.com>
parents: 704
diff changeset
83
706
16042667ab51 ui for making a new subterm
Drew Perttula <drewp@bigasterisk.com>
parents: 705
diff changeset
84 def onNewSubterm(self, *args):
707
c4a38a247b26 cleanup. 'create' menu
Drew Perttula <drewp@bigasterisk.com>
parents: 706
diff changeset
85 dialog = self.wtree.get_object("newSubterm")
706
16042667ab51 ui for making a new subterm
Drew Perttula <drewp@bigasterisk.com>
parents: 705
diff changeset
86 # the plan is to autocomplete this on existing subterm names
16042667ab51 ui for making a new subterm
Drew Perttula <drewp@bigasterisk.com>
parents: 705
diff changeset
87 # (but let you make one up, too)
16042667ab51 ui for making a new subterm
Drew Perttula <drewp@bigasterisk.com>
parents: 705
diff changeset
88 entry = self.wtree.get_object("newSubtermName").get_children()[0]
16042667ab51 ui for making a new subterm
Drew Perttula <drewp@bigasterisk.com>
parents: 705
diff changeset
89 entry.set_text("")
707
c4a38a247b26 cleanup. 'create' menu
Drew Perttula <drewp@bigasterisk.com>
parents: 706
diff changeset
90 entry.grab_focus()
c4a38a247b26 cleanup. 'create' menu
Drew Perttula <drewp@bigasterisk.com>
parents: 706
diff changeset
91 if dialog.run() == 1:
706
16042667ab51 ui for making a new subterm
Drew Perttula <drewp@bigasterisk.com>
parents: 705
diff changeset
92 newname = entry.get_text()
16042667ab51 ui for making a new subterm
Drew Perttula <drewp@bigasterisk.com>
parents: 705
diff changeset
93 uri = L9['sub/%s' % newname]
16042667ab51 ui for making a new subterm
Drew Perttula <drewp@bigasterisk.com>
parents: 705
diff changeset
94 self.graph.add((uri, RDF.type, L9.Subterm))
16042667ab51 ui for making a new subterm
Drew Perttula <drewp@bigasterisk.com>
parents: 705
diff changeset
95 self.graph.add((uri, RDFS.label, Literal(newname)))
16042667ab51 ui for making a new subterm
Drew Perttula <drewp@bigasterisk.com>
parents: 705
diff changeset
96 add_one_subterm(self.graph, uri,
16042667ab51 ui for making a new subterm
Drew Perttula <drewp@bigasterisk.com>
parents: 705
diff changeset
97 self.curveset, self.subterms,
16042667ab51 ui for making a new subterm
Drew Perttula <drewp@bigasterisk.com>
parents: 705
diff changeset
98 self.wtree.get_object("subterms"),
16042667ab51 ui for making a new subterm
Drew Perttula <drewp@bigasterisk.com>
parents: 705
diff changeset
99 None, show=True)
707
c4a38a247b26 cleanup. 'create' menu
Drew Perttula <drewp@bigasterisk.com>
parents: 706
diff changeset
100 if self.wtree.get_object("newSubtermMakeCurve").get_active():
706
16042667ab51 ui for making a new subterm
Drew Perttula <drewp@bigasterisk.com>
parents: 705
diff changeset
101 self.curveset.new_curve(newname)
16042667ab51 ui for making a new subterm
Drew Perttula <drewp@bigasterisk.com>
parents: 705
diff changeset
102
707
c4a38a247b26 cleanup. 'create' menu
Drew Perttula <drewp@bigasterisk.com>
parents: 706
diff changeset
103 dialog.hide()
706
16042667ab51 ui for making a new subterm
Drew Perttula <drewp@bigasterisk.com>
parents: 705
diff changeset
104
701
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
105 def refreshTheme(self):
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
106 gtk.rc_reparse_all()
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
107 reactor.callLater(1, self.refreshTheme)
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
108
700
d5692ab6bc2a fix quit and ctrl-q by using kill -9
Drew Perttula <drewp@bigasterisk.com>
parents: 699
diff changeset
109 def onQuit(self, *args):
d5692ab6bc2a fix quit and ctrl-q by using kill -9
Drew Perttula <drewp@bigasterisk.com>
parents: 699
diff changeset
110 reactor.crash()
d5692ab6bc2a fix quit and ctrl-q by using kill -9
Drew Perttula <drewp@bigasterisk.com>
parents: 699
diff changeset
111 # there's a hang after this, maybe in sem_wait in two
d5692ab6bc2a fix quit and ctrl-q by using kill -9
Drew Perttula <drewp@bigasterisk.com>
parents: 699
diff changeset
112 # threads. I don't know whose they are.
d5692ab6bc2a fix quit and ctrl-q by using kill -9
Drew Perttula <drewp@bigasterisk.com>
parents: 699
diff changeset
113 os.kill(os.getpid(), signal.SIGKILL)
d5692ab6bc2a fix quit and ctrl-q by using kill -9
Drew Perttula <drewp@bigasterisk.com>
parents: 699
diff changeset
114
711
e94989da079c more curve editor bindings. delete signal isn't done
drewp@bigasterisk.com
parents: 708
diff changeset
115 def onDelete(self, *args):
e94989da079c more curve editor bindings. delete signal isn't done
drewp@bigasterisk.com
parents: 708
diff changeset
116 self.curvesetView.onDelete()
e94989da079c more curve editor bindings. delete signal isn't done
drewp@bigasterisk.com
parents: 708
diff changeset
117
708
10ee0756a119 new python console
Drew Perttula <drewp@bigasterisk.com>
parents: 707
diff changeset
118 def onPythonConsole(self, item):
10ee0756a119 new python console
Drew Perttula <drewp@bigasterisk.com>
parents: 707
diff changeset
119 togglePyConsole(self, item, self.__dict__)
10ee0756a119 new python console
Drew Perttula <drewp@bigasterisk.com>
parents: 707
diff changeset
120
699
d12bc8919d6e ported the zoom control
Drew Perttula <drewp@bigasterisk.com>
parents: 698
diff changeset
121 def onSeeCurrentTime(self, item):
d12bc8919d6e ported the zoom control
Drew Perttula <drewp@bigasterisk.com>
parents: 698
diff changeset
122 dispatcher.send("see time")
d12bc8919d6e ported the zoom control
Drew Perttula <drewp@bigasterisk.com>
parents: 698
diff changeset
123
d12bc8919d6e ported the zoom control
Drew Perttula <drewp@bigasterisk.com>
parents: 698
diff changeset
124 def onSeeTimeUntilEnd(self, item):
d12bc8919d6e ported the zoom control
Drew Perttula <drewp@bigasterisk.com>
parents: 698
diff changeset
125 dispatcher.send("see time until end")
d12bc8919d6e ported the zoom control
Drew Perttula <drewp@bigasterisk.com>
parents: 698
diff changeset
126
d12bc8919d6e ported the zoom control
Drew Perttula <drewp@bigasterisk.com>
parents: 698
diff changeset
127 def onZoomAll(self, item):
d12bc8919d6e ported the zoom control
Drew Perttula <drewp@bigasterisk.com>
parents: 698
diff changeset
128 dispatcher.send("show all")
694
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
129
698
2aac2ef23495 time cursor, control-p over curveviews
Drew Perttula <drewp@bigasterisk.com>
parents: 697
diff changeset
130 def onPlayPause(self, item):
2aac2ef23495 time cursor, control-p over curveviews
Drew Perttula <drewp@bigasterisk.com>
parents: 697
diff changeset
131 # since the X coord in a curveview affects the handling, one
2aac2ef23495 time cursor, control-p over curveviews
Drew Perttula <drewp@bigasterisk.com>
parents: 697
diff changeset
132 # of them may be able to pick this up
2aac2ef23495 time cursor, control-p over curveviews
Drew Perttula <drewp@bigasterisk.com>
parents: 697
diff changeset
133 results = dispatcher.send("onPlayPause")
2aac2ef23495 time cursor, control-p over curveviews
Drew Perttula <drewp@bigasterisk.com>
parents: 697
diff changeset
134 times = [t for listener, t in results if t is not None]
2aac2ef23495 time cursor, control-p over curveviews
Drew Perttula <drewp@bigasterisk.com>
parents: 697
diff changeset
135 self.music.playOrPause(t=times[0] if times else None)
2aac2ef23495 time cursor, control-p over curveviews
Drew Perttula <drewp@bigasterisk.com>
parents: 697
diff changeset
136
694
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
137 def onSave(self, *args):
703
54a3dcba6597 save works
Drew Perttula <drewp@bigasterisk.com>
parents: 702
diff changeset
138 savekey(self.song, self.subterms, self.curveset)
694
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
139
706
16042667ab51 ui for making a new subterm
Drew Perttula <drewp@bigasterisk.com>
parents: 705
diff changeset
140 def add_subterms_for_song(self, song, curveset, subterms):
16042667ab51 ui for making a new subterm
Drew Perttula <drewp@bigasterisk.com>
parents: 705
diff changeset
141 master = self.wtree.get_object("subterms")
692
ccdd04f4ca7d subterm display is working
Drew Perttula <drewp@bigasterisk.com>
parents: 691
diff changeset
142 for st in self.graph.objects(song, L9['subterm']):
ccdd04f4ca7d subterm display is working
Drew Perttula <drewp@bigasterisk.com>
parents: 691
diff changeset
143 log.info("song %s has subterm %s", song, st)
ccdd04f4ca7d subterm display is working
Drew Perttula <drewp@bigasterisk.com>
parents: 691
diff changeset
144 add_one_subterm(self.graph,
ccdd04f4ca7d subterm display is working
Drew Perttula <drewp@bigasterisk.com>
parents: 691
diff changeset
145 self.graph.value(st, L9['sub']),
ccdd04f4ca7d subterm display is working
Drew Perttula <drewp@bigasterisk.com>
parents: 691
diff changeset
146 curveset,
ccdd04f4ca7d subterm display is working
Drew Perttula <drewp@bigasterisk.com>
parents: 691
diff changeset
147 subterms,
ccdd04f4ca7d subterm display is working
Drew Perttula <drewp@bigasterisk.com>
parents: 691
diff changeset
148 master,
ccdd04f4ca7d subterm display is working
Drew Perttula <drewp@bigasterisk.com>
parents: 691
diff changeset
149 self.graph.value(st, L9['expression']))
ccdd04f4ca7d subterm display is working
Drew Perttula <drewp@bigasterisk.com>
parents: 691
diff changeset
150 master.show_all()
ccdd04f4ca7d subterm display is working
Drew Perttula <drewp@bigasterisk.com>
parents: 691
diff changeset
151
694
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
152 def makeStatusLines(self, master):
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
153 """various labels that listen for dispatcher signals"""
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
154 for row, (signame, textfilter) in enumerate([
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
155 ('input time', lambda t: "%.2fs"%t),
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
156 ('output levels',
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
157 lambda levels: textwrap.fill("; ".join(["%s:%.2f"%(n,v)
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
158 for n,v in
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
159 levels.items()[:5]
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
160 if v>0]),70)),
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
161 ('update period', lambda t: "%.1fms"%(t*1000)),
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
162 ('update status', lambda x: str(x)),
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
163 ]):
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
164 key = gtk.Label("%s:" % signame)
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
165 value = gtk.Label("")
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
166 master.resize(row + 1, 2)
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
167 master.attach(key, 0, 1, row, row + 1)
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
168 master.attach(value, 1, 2, row, row + 1)
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
169 key.set_alignment(1, 0)
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
170 value.set_alignment(0, 0)
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
171
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
172 dispatcher.connect(lambda val, value=value, tf=textfilter:
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
173 value.set_text(tf(val)),
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
174 signame, weak=False)
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
175 master.show_all()
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
176
701
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
177 def refreshCurveView(self):
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
178 wtree = self.wtree
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
179 mtimes = [os.path.getmtime(f) for f in [
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
180 'light9/curvecalc/curveview.py',
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
181 'light9/curvecalc/zoomcontrol.py',
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
182 ]]
694
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
183
701
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
184 if (not hasattr(self, 'curvesetView') or
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
185 self.curvesetView._mtimes != mtimes):
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
186 print "reload curveview.py"
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
187 curvesVBox = wtree.get_object("curves")
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
188 zoomControlBox = wtree.get_object("zoomControlBox")
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
189 [curvesVBox.remove(c) for c in curvesVBox.get_children()]
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
190 [zoomControlBox.remove(c) for c in
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
191 zoomControlBox.get_children()]
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
192 try:
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
193 linecache.clearcache()
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
194 reload(curveview)
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
195 # mem problem somewhere; need to hold a ref to this
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
196 self.curvesetView = curveview.Curvesetview(
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
197 curvesVBox, zoomControlBox, self.curveset)
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
198 self.curvesetView._mtimes = mtimes
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
199
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
200 # this is scheduled after some tk shuffling, to
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
201 # try to minimize the number of times we redraw
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
202 # the curve at startup. If tk is very slow, it's
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
203 # ok. You'll just get some wasted redraws.
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
204 self.curvesetView.goLive()
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
205 except Exception, e:
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
206 print "reload failed:", e
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
207 if self.opts.reload:
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
208 reactor.callLater(1, self.refreshCurveView)
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
209
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
210 def onReloadSubs(self, *args): # wants to be ctrl-r too
694
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
211 dispatcher.send('reload all subs')
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
212
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
213
505
cbc98de2ab06 refactor curveCalc toplevel
drewp@bigasterisk.com
parents: 493
diff changeset
214 def main():
680
ad17b0a09f5c CC more startup logging, timing option to quit after init
drewp@bigasterisk.com
parents: 641
diff changeset
215 startTime = time.time()
505
cbc98de2ab06 refactor curveCalc toplevel
drewp@bigasterisk.com
parents: 493
diff changeset
216 parser = optparse.OptionParser()
551
ad5043f70fda bin/curvecalc (with no song choice) defaults to whatever-ascoltami-is-currently-on
drewp@bigasterisk.com
parents: 532
diff changeset
217 parser.set_usage("%prog [opts] [songURI]")
505
cbc98de2ab06 refactor curveCalc toplevel
drewp@bigasterisk.com
parents: 493
diff changeset
218 parser.add_option("--sliders", action='store_true',
cbc98de2ab06 refactor curveCalc toplevel
drewp@bigasterisk.com
parents: 493
diff changeset
219 help='use hardware sliders')
cbc98de2ab06 refactor curveCalc toplevel
drewp@bigasterisk.com
parents: 493
diff changeset
220 parser.add_option("--skip-music", action='store_true',
cbc98de2ab06 refactor curveCalc toplevel
drewp@bigasterisk.com
parents: 493
diff changeset
221 help="ignore music and smooth_music curve files")
680
ad17b0a09f5c CC more startup logging, timing option to quit after init
drewp@bigasterisk.com
parents: 641
diff changeset
222 parser.add_option("--debug", action="store_true",
ad17b0a09f5c CC more startup logging, timing option to quit after init
drewp@bigasterisk.com
parents: 641
diff changeset
223 help="log at DEBUG")
701
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
224 parser.add_option("--reload", action="store_true",
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
225 help="live reload of themes and code")
680
ad17b0a09f5c CC more startup logging, timing option to quit after init
drewp@bigasterisk.com
parents: 641
diff changeset
226 parser.add_option("--startup-only", action='store_true',
ad17b0a09f5c CC more startup logging, timing option to quit after init
drewp@bigasterisk.com
parents: 641
diff changeset
227 help="quit after loading everything (for timing tests)")
505
cbc98de2ab06 refactor curveCalc toplevel
drewp@bigasterisk.com
parents: 493
diff changeset
228 opts, args = parser.parse_args()
cbc98de2ab06 refactor curveCalc toplevel
drewp@bigasterisk.com
parents: 493
diff changeset
229
590
0cf00fffd921 logging
drewp@bigasterisk.com
parents: 551
diff changeset
230 logging.basicConfig(format="%(asctime)s %(levelname)-5s %(name)s %(filename)s:%(lineno)d: %(message)s")
680
ad17b0a09f5c CC more startup logging, timing option to quit after init
drewp@bigasterisk.com
parents: 641
diff changeset
231 log.setLevel(logging.DEBUG if opts.debug else logging.INFO)
590
0cf00fffd921 logging
drewp@bigasterisk.com
parents: 551
diff changeset
232
680
ad17b0a09f5c CC more startup logging, timing option to quit after init
drewp@bigasterisk.com
parents: 641
diff changeset
233 log.debug("startup: music %s", time.time() - startTime)
505
cbc98de2ab06 refactor curveCalc toplevel
drewp@bigasterisk.com
parents: 493
diff changeset
234 try:
cbc98de2ab06 refactor curveCalc toplevel
drewp@bigasterisk.com
parents: 493
diff changeset
235 song = URIRef(args[0])
cbc98de2ab06 refactor curveCalc toplevel
drewp@bigasterisk.com
parents: 493
diff changeset
236 except IndexError:
551
ad5043f70fda bin/curvecalc (with no song choice) defaults to whatever-ascoltami-is-currently-on
drewp@bigasterisk.com
parents: 532
diff changeset
237 song = currentlyPlayingSong()
505
cbc98de2ab06 refactor curveCalc toplevel
drewp@bigasterisk.com
parents: 493
diff changeset
238
701
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
239 music = Music()
516
73b181155555 curvecalc ui touchups, adjustable pane, curve draw speedup, restructured main layout code
drewp@bigasterisk.com
parents: 505
diff changeset
240 graph = makeGraph()
691
62d83d456f2e curvecalc start gtk porting
drewp@bigasterisk.com
parents: 690
diff changeset
241
505
cbc98de2ab06 refactor curveCalc toplevel
drewp@bigasterisk.com
parents: 493
diff changeset
242 curveset = Curveset(sliders=opts.sliders)
516
73b181155555 curvecalc ui touchups, adjustable pane, curve draw speedup, restructured main layout code
drewp@bigasterisk.com
parents: 505
diff changeset
243 subterms = []
505
cbc98de2ab06 refactor curveCalc toplevel
drewp@bigasterisk.com
parents: 493
diff changeset
244
704
d5a9933a2222 don't reload curve files upon curve code reload
Drew Perttula <drewp@bigasterisk.com>
parents: 703
diff changeset
245 # curvesetview must already exist, since this
d5a9933a2222 don't reload curve files upon curve code reload
Drew Perttula <drewp@bigasterisk.com>
parents: 703
diff changeset
246 # makes 'add_curve' signals for all the initial
d5a9933a2222 don't reload curve files upon curve code reload
Drew Perttula <drewp@bigasterisk.com>
parents: 703
diff changeset
247 # curves.
d5a9933a2222 don't reload curve files upon curve code reload
Drew Perttula <drewp@bigasterisk.com>
parents: 703
diff changeset
248 curveset.load(basename=os.path.join(
d5a9933a2222 don't reload curve files upon curve code reload
Drew Perttula <drewp@bigasterisk.com>
parents: 703
diff changeset
249 showconfig.curvesDir(),
d5a9933a2222 don't reload curve files upon curve code reload
Drew Perttula <drewp@bigasterisk.com>
parents: 703
diff changeset
250 showconfig.songFilenameFromURI(song)),
d5a9933a2222 don't reload curve files upon curve code reload
Drew Perttula <drewp@bigasterisk.com>
parents: 703
diff changeset
251 skipMusic=opts.skip_music)
d5a9933a2222 don't reload curve files upon curve code reload
Drew Perttula <drewp@bigasterisk.com>
parents: 703
diff changeset
252
637
af5539fe35a7 CC startup doesn't need a subterms file. it'll make the first one
Drew Perttula <drewp@bigasterisk.com>
parents: 636
diff changeset
253 subtermPath = graphPathForSubterms(song)
af5539fe35a7 CC startup doesn't need a subterms file. it'll make the first one
Drew Perttula <drewp@bigasterisk.com>
parents: 636
diff changeset
254 try:
af5539fe35a7 CC startup doesn't need a subterms file. it'll make the first one
Drew Perttula <drewp@bigasterisk.com>
parents: 636
diff changeset
255 graph.parse(subtermPath, format='n3')
af5539fe35a7 CC startup doesn't need a subterms file. it'll make the first one
Drew Perttula <drewp@bigasterisk.com>
parents: 636
diff changeset
256 except urllib2.URLError, e:
af5539fe35a7 CC startup doesn't need a subterms file. it'll make the first one
Drew Perttula <drewp@bigasterisk.com>
parents: 636
diff changeset
257 if e.reason.errno != 2:
af5539fe35a7 CC startup doesn't need a subterms file. it'll make the first one
Drew Perttula <drewp@bigasterisk.com>
parents: 636
diff changeset
258 raise
af5539fe35a7 CC startup doesn't need a subterms file. it'll make the first one
Drew Perttula <drewp@bigasterisk.com>
parents: 636
diff changeset
259 log.info("%s not found, starting with empty graph" % subtermPath)
516
73b181155555 curvecalc ui touchups, adjustable pane, curve draw speedup, restructured main layout code
drewp@bigasterisk.com
parents: 505
diff changeset
260
680
ad17b0a09f5c CC more startup logging, timing option to quit after init
drewp@bigasterisk.com
parents: 641
diff changeset
261 log.debug("startup: output %s", time.time() - startTime)
516
73b181155555 curvecalc ui touchups, adjustable pane, curve draw speedup, restructured main layout code
drewp@bigasterisk.com
parents: 505
diff changeset
262 out = Output(subterms, music)
505
cbc98de2ab06 refactor curveCalc toplevel
drewp@bigasterisk.com
parents: 493
diff changeset
263
cbc98de2ab06 refactor curveCalc toplevel
drewp@bigasterisk.com
parents: 493
diff changeset
264 musicfilename = showconfig.songOnDisk(song)
cbc98de2ab06 refactor curveCalc toplevel
drewp@bigasterisk.com
parents: 493
diff changeset
265 maxtime = wavelength(musicfilename)
516
73b181155555 curvecalc ui touchups, adjustable pane, curve draw speedup, restructured main layout code
drewp@bigasterisk.com
parents: 505
diff changeset
266 dispatcher.connect(lambda: maxtime, "get max time", weak=False)
73b181155555 curvecalc ui touchups, adjustable pane, curve draw speedup, restructured main layout code
drewp@bigasterisk.com
parents: 505
diff changeset
267
698
2aac2ef23495 time cursor, control-p over curveviews
Drew Perttula <drewp@bigasterisk.com>
parents: 697
diff changeset
268 start = Main(graph, opts, song, curveset, subterms, music)
692
ccdd04f4ca7d subterm display is working
Drew Perttula <drewp@bigasterisk.com>
parents: 691
diff changeset
269
694
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
270 dispatcher.send("max time", maxtime=maxtime)
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
271 dispatcher.send("show all")
34dacd800505 eval loop is running, music drives lights. started to add goocanvas curve view
Drew Perttula <drewp@bigasterisk.com>
parents: 692
diff changeset
272
692
ccdd04f4ca7d subterm display is working
Drew Perttula <drewp@bigasterisk.com>
parents: 691
diff changeset
273 if opts.startup_only:
ccdd04f4ca7d subterm display is working
Drew Perttula <drewp@bigasterisk.com>
parents: 691
diff changeset
274 log.debug("quitting now because of --startup-only")
ccdd04f4ca7d subterm display is working
Drew Perttula <drewp@bigasterisk.com>
parents: 691
diff changeset
275 return
ccdd04f4ca7d subterm display is working
Drew Perttula <drewp@bigasterisk.com>
parents: 691
diff changeset
276
701
417e23dc0af0 add marble-ice theme. use --reload to opt in to all autoreloading
Drew Perttula <drewp@bigasterisk.com>
parents: 700
diff changeset
277 prof.run(reactor.run, profile=False)
505
cbc98de2ab06 refactor curveCalc toplevel
drewp@bigasterisk.com
parents: 493
diff changeset
278
cbc98de2ab06 refactor curveCalc toplevel
drewp@bigasterisk.com
parents: 493
diff changeset
279 main()