Changeset - 35468f1dcf38
[Not reviewed]
default
0 2 0
drewp@bigasterisk.com - 3 years ago 2022-06-01 19:20:11
drewp@bigasterisk.com
comments
2 files changed with 2 insertions and 0 deletions:
0 comments (0 inline, 0 general)
light9/web/timeline/Note.coffee
Show inline comments
 
log = debug('timeline')
 
debug.enable('*')
 

	
 
Drawing = window.Drawing
 
ROW_COUNT = 7
 

	
 
# Maintains a pixi object, some adjusters, and inlineattrs corresponding to a note
 
# in the graph.
 
class Note
 
  constructor: (@parentElem, @container, @project, @graph, @selection, @uri, @setAdjuster, @song, @viewState, @brickLayout) ->
 
    @adjusterIds = new Set() # id string
 
    @updateSoon = _.debounce(@update.bind(@), 30)
 

	
 
  initWatchers: ->
 
    @graph.runHandler(@update.bind(@), "note update #{@uri.value}")
 
    ko.computed @update.bind(@)
 

	
 
  destroy: ->
 
    log('destroy', @uri.value)
 
    @isDetached = true
 
    @clearAdjusters()
 
    @parentElem.updateInlineAttrs(@uri, null)
 

	
 
  clearAdjusters: ->
 
    @adjusterIds.forEach (i) =>
 
      @setAdjuster(i, null)
 
    @adjusterIds.clear()
 

	
 
  getCurvePoints: (subj, curveAttr) ->
 
    U = (x) => @graph.Uri(x)
 
    originTime = @graph.floatValue(subj, U(':originTime'))
 

	
 
    for curve in @graph.objects(subj, U(':curve'))
 
      # todo: maybe shoudl be :effectAttr?
 
      if @graph.uriValue(curve, U(':attr')).equals(curveAttr)
 
        return @project.getCurvePoints(curve, originTime)
 
    throw new Error("curve #{@uri.value} has no attr #{curveAttr.value}")
 

	
 
  midPoint: (i0, i1) ->
 
    p0 = @worldPts[i0]
 
    p1 = @worldPts[i1]
 
    p0.x(.5).add(p1.x(.5))
 

	
 
  _planDrawing: ->
 
    U = (x) => @graph.Uri(x)
 
    [pointUris, worldPts] = @getCurvePoints(@uri, U(':strength'))
 
    effect = @graph.uriValue(@uri, U(':effectClass'))
 

	
 
    yForV = @brickLayout.yForVFor(@)
 
    dependOn = [@viewState.zoomSpec.t1(),
 
                @viewState.zoomSpec.t2(),
 
                @viewState.width()]
 
    screenPts = (new PIXI.Point(@viewState.zoomInX(pt.e(1)),
 
                                yForV(pt.e(2))) for pt in worldPts)
 
    return {
 
      yForV: yForV
 
      worldPts: worldPts
 
      screenPts: screenPts
 
      effect: effect
 
      hover: @uri.equals(@selection.hover())
 
      selected: @selection.selected().filter((s) => s.equals(@uri)).length
 
    }
 

	
 
  onRowChange: ->
 
    @clearAdjusters()
 
    @updateSoon()
 

	
 
  redraw: (params) ->
 
    # no observable or graph deps in here
 
    @container.removeChildren()
 
    @graphics = new PIXI.Graphics({nativeLines: false})
 
    @graphics.interactive = true
 
    @container.addChild(@graphics)
 

	
 
    if params.hover
 
      @_traceBorder(params.screenPts, 12, 0x888888)
 
    if params.selected
 
      @_traceBorder(params.screenPts, 6, 0xff2900)
 

	
 
    shape = new PIXI.Polygon(params.screenPts)
 
    @graphics.beginFill(@_noteColor(params.effect), .313)
 
    @graphics.drawShape(shape)
light9/web/timeline/Project.coffee
Show inline comments
 
@@ -7,86 +7,87 @@ ROW_COUNT = 7
 
class Project
 
  constructor: (@graph) ->
 

	
 
  makeEffect: (uri) ->
 
    U = (x) => @graph.Uri(x)
 
    effect = U(uri.value + '/effect')
 
    quad = (s, p, o) => @graph.Quad(s, p, o, effect)
 

	
 
    quads = [
 
      quad(effect, U('rdf:type'), U(':Effect')),
 
      quad(effect, U(':copiedFrom'), uri),
 
      quad(effect, U('rdfs:label'), @graph.Literal(uri.replace(/.*capture\//, ''))),
 
      quad(effect, U(':publishAttr'), U(':strength')),
 
      ]
 

	
 
    fromSettings = @graph.objects(uri, U(':setting'))
 

	
 
    toSettings = @graph.nextNumberedResources(effect + '_set', fromSettings.length)
 

	
 
    for fs in fromSettings
 
      ts = toSettings.pop()
 
      # full copies of these since I may have to delete captures
 
      quads.push(quad(effect, U(':setting'), ts))
 
      quads.push(quad(ts, U(':device'), @graph.uriValue(fs, U(':device'))))
 
      quads.push(quad(ts, U(':deviceAttr'), @graph.uriValue(fs, U(':deviceAttr'))))
 
      try
 
        quads.push(quad(ts, U(':value'), @graph.uriValue(fs, U(':value'))))
 
      catch
 
        quads.push(quad(ts, U(':scaledValue'), @graph.uriValue(fs, U(':scaledValue'))))
 

	
 
    @graph.applyAndSendPatch({delQuads: [], addQuads: quads})
 
    return effect
 

	
 
  makeNewNote: (song, effect, dropTime, desiredWidthT) ->
 
    U = (x) => @graph.Uri(x)
 
    quad = (s, p, o) => @graph.Quad(s, p, o, song)
 

	
 
    newNote = @graph.nextNumberedResource("#{song.value}/n")
 
    newCurve = @graph.nextNumberedResource("#{newNote.value}c")
 
    points = @graph.nextNumberedResources("#{newCurve.value}p", 4)
 

	
 
    curveQuads = [
 
        quad(song, U(':note'), newNote)
 
        quad(newNote, U('rdf:type'), U(':Note'))
 
        quad(newNote, U(':originTime'), @graph.LiteralRoundedFloat(dropTime))
 
        quad(newNote, U(':effectClass'), effect)
 
        quad(newNote, U(':curve'), newCurve)
 
        quad(newCurve, U('rdf:type'), U(':Curve'))
 
        # todo: maybe shoudl be :effectAttr?
 
        quad(newCurve, U(':attr'), U(':strength'))
 
      ]
 

	
 
    pointQuads = []
 
    for i in [0...4]
 
      pt = points[i]
 
      pointQuads.push(quad(newCurve, U(':point'), pt))
 
      pointQuads.push(quad(pt, U(':time'), @graph.LiteralRoundedFloat(i/3 * desiredWidthT)))
 
      pointQuads.push(quad(pt, U(':value'), @graph.LiteralRoundedFloat(i == 1 or i == 2)))
 

	
 
    patch = {
 
      delQuads: []
 
      addQuads: curveQuads.concat(pointQuads)
 
    }
 
    @graph.applyAndSendPatch(patch)
 

	
 
  getCurvePoints: (curve, xOffset) ->
 
    worldPts = []
 
    uris = @graph.objects(curve, @graph.Uri(':point'))
 
    for pt in uris
 
      tm = @graph.floatValue(pt, @graph.Uri(':time'))
 
      val = @graph.floatValue(pt, @graph.Uri(':value'))
 
      v = $V([xOffset + tm, val])
 
      v.uri = pt
 
      worldPts.push(v)
 
    worldPts.sort((a,b) -> a.e(1) - b.e(1))
 
    return [uris, worldPts]
 

	
 
  curveWidth: (worldPts) ->
 
    tMin = @graph.floatValue(worldPts[0].uri, @graph.Uri(':time'))
 
    tMax = @graph.floatValue(worldPts[3].uri, @graph.Uri(':time'))
 
    tMax - tMin
 

	
 
  deleteNote: (song, note, selection) ->
 
    patch = {delQuads: [@graph.Quad(song, graph.Uri(':note'), note, song)], addQuads: []}
 
    @graph.applyAndSendPatch(patch)
 
    if note in selection.selected()
 
      selection.selected(_.without(selection.selected(), note))
0 comments (0 inline, 0 general)