comparison web/timeline/Project.coffee @ 2376:4556eebe5d73

topdir reorgs; let pdm have its src/ dir; separate vite area from light9/
author drewp@bigasterisk.com
date Sun, 12 May 2024 19:02:10 -0700
parents light9/web/timeline/Project.coffee@35468f1dcf38
children
comparison
equal deleted inserted replaced
2375:623836db99af 2376:4556eebe5d73
1 log = debug('timeline')
2 debug.enable('*')
3
4 Drawing = window.Drawing
5 ROW_COUNT = 7
6
7 class Project
8 constructor: (@graph) ->
9
10 makeEffect: (uri) ->
11 U = (x) => @graph.Uri(x)
12 effect = U(uri.value + '/effect')
13 quad = (s, p, o) => @graph.Quad(s, p, o, effect)
14
15 quads = [
16 quad(effect, U('rdf:type'), U(':Effect')),
17 quad(effect, U(':copiedFrom'), uri),
18 quad(effect, U('rdfs:label'), @graph.Literal(uri.replace(/.*capture\//, ''))),
19 quad(effect, U(':publishAttr'), U(':strength')),
20 ]
21
22 fromSettings = @graph.objects(uri, U(':setting'))
23
24 toSettings = @graph.nextNumberedResources(effect + '_set', fromSettings.length)
25
26 for fs in fromSettings
27 ts = toSettings.pop()
28 # full copies of these since I may have to delete captures
29 quads.push(quad(effect, U(':setting'), ts))
30 quads.push(quad(ts, U(':device'), @graph.uriValue(fs, U(':device'))))
31 quads.push(quad(ts, U(':deviceAttr'), @graph.uriValue(fs, U(':deviceAttr'))))
32 try
33 quads.push(quad(ts, U(':value'), @graph.uriValue(fs, U(':value'))))
34 catch
35 quads.push(quad(ts, U(':scaledValue'), @graph.uriValue(fs, U(':scaledValue'))))
36
37 @graph.applyAndSendPatch({delQuads: [], addQuads: quads})
38 return effect
39
40 makeNewNote: (song, effect, dropTime, desiredWidthT) ->
41 U = (x) => @graph.Uri(x)
42 quad = (s, p, o) => @graph.Quad(s, p, o, song)
43
44 newNote = @graph.nextNumberedResource("#{song.value}/n")
45 newCurve = @graph.nextNumberedResource("#{newNote.value}c")
46 points = @graph.nextNumberedResources("#{newCurve.value}p", 4)
47
48 curveQuads = [
49 quad(song, U(':note'), newNote)
50 quad(newNote, U('rdf:type'), U(':Note'))
51 quad(newNote, U(':originTime'), @graph.LiteralRoundedFloat(dropTime))
52 quad(newNote, U(':effectClass'), effect)
53 quad(newNote, U(':curve'), newCurve)
54 quad(newCurve, U('rdf:type'), U(':Curve'))
55 # todo: maybe shoudl be :effectAttr?
56 quad(newCurve, U(':attr'), U(':strength'))
57 ]
58
59 pointQuads = []
60 for i in [0...4]
61 pt = points[i]
62 pointQuads.push(quad(newCurve, U(':point'), pt))
63 pointQuads.push(quad(pt, U(':time'), @graph.LiteralRoundedFloat(i/3 * desiredWidthT)))
64 pointQuads.push(quad(pt, U(':value'), @graph.LiteralRoundedFloat(i == 1 or i == 2)))
65
66 patch = {
67 delQuads: []
68 addQuads: curveQuads.concat(pointQuads)
69 }
70 @graph.applyAndSendPatch(patch)
71
72 getCurvePoints: (curve, xOffset) ->
73 worldPts = []
74 uris = @graph.objects(curve, @graph.Uri(':point'))
75 for pt in uris
76 tm = @graph.floatValue(pt, @graph.Uri(':time'))
77 val = @graph.floatValue(pt, @graph.Uri(':value'))
78 v = $V([xOffset + tm, val])
79 v.uri = pt
80 worldPts.push(v)
81 worldPts.sort((a,b) -> a.e(1) - b.e(1))
82 return [uris, worldPts]
83
84 curveWidth: (worldPts) ->
85 tMin = @graph.floatValue(worldPts[0].uri, @graph.Uri(':time'))
86 tMax = @graph.floatValue(worldPts[3].uri, @graph.Uri(':time'))
87 tMax - tMin
88
89 deleteNote: (song, note, selection) ->
90 patch = {delQuads: [@graph.Quad(song, graph.Uri(':note'), note, song)], addQuads: []}
91 @graph.applyAndSendPatch(patch)
92 if note in selection.selected()
93 selection.selected(_.without(selection.selected(), note))