changeset 1771:792bf30de608

brick mode works. fix some refresh issues. Ignore-this: a613da1b0281ef8774e0df90d1e39c82
author Drew Perttula <drewp@bigasterisk.com>
date Sun, 03 Jun 2018 10:37:00 +0000
parents 48e4e25f37a3
children 66a55cb17cbf
files light9/web/timeline/brick_layout.coffee light9/web/timeline/timeline-elements.html light9/web/timeline/timeline.coffee light9/web/timeline/viewstate.coffee
diffstat 4 files changed, 67 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/light9/web/timeline/brick_layout.coffee	Sun Jun 03 10:37:00 2018 +0000
@@ -0,0 +1,52 @@
+
+class window.BrickLayout
+  constructor: (@viewState, @numRows) ->
+    @noteRow = {} # uristr: row, t0, t1, onRowChange
+    
+  addNote: (n, onRowChange) ->
+    @noteRow[n.uri.value] = {row: 0, t0: 0, t1: 0, onRowChange: onRowChange}
+    
+  setNoteSpan: (n, t0, t1) ->
+    @noteRow[n.uri.value].t0 = t0
+    @noteRow[n.uri.value].t1 = t1
+    @_recompute()
+    
+  delNote: (n) ->
+    delete @noteRow[n.uri.value]
+    @_recompute()
+    
+  _recompute: ->
+    for u, row of @noteRow
+      row.prev = row.row
+      row.row = null
+    overlap = (a, b) -> a.t0 < b.t1 and a.t1 > b.t0
+
+    notesByWidth = _.sortBy(
+      ({dur: row.t1 - row.t0 + row.t0 * .0001, uri: u} for u, row of @noteRow),
+      'dur')
+    notesByWidth.reverse()
+
+    for n in notesByWidth
+      blockedRows = new Set()
+      for u, other of @noteRow
+        if other.row != null
+          if overlap(other, @noteRow[n.uri])
+            blockedRows.add(other.row)
+
+      for r in [0 ... @numRows]
+        if not blockedRows.has(r)
+          @noteRow[n.uri].row = r
+          break
+      if @noteRow[n.uri].row == null
+        log("warning: couldn't place #{n.uri}")
+        @noteRow[n.uri].row = 0
+      if @noteRow[n.uri].row != @noteRow[n.uri].prev
+        @noteRow[n.uri].onRowChange()
+          
+  rowBottom: (row) -> @viewState.rowsY() + 20 + 150 * row + 140
+  
+  yForVFor: (n) ->
+    row = @noteRow[n.uri.value].row
+    rowBottom = @rowBottom(row)
+    rowTop = rowBottom - 140
+    (v) => rowBottom + (rowTop - rowBottom) * v      
--- a/light9/web/timeline/timeline-elements.html	Sun Jun 03 04:51:43 2018 +0000
+++ b/light9/web/timeline/timeline-elements.html	Sun Jun 03 10:37:00 2018 +0000
@@ -205,6 +205,7 @@
 <script src="drawing.js"></script>
 <script src="../coffee_element.js"></script>
 <script src="viewstate.js"></script>
+<script src="brick_layout.js"></script>
 <script src="adjustable.js"></script>
 <script src="adjusters.js"></script>
 <script src="timeline.js"></script>
--- a/light9/web/timeline/timeline.coffee	Sun Jun 03 04:51:43 2018 +0000
+++ b/light9/web/timeline/timeline.coffee	Sun Jun 03 10:37:00 2018 +0000
@@ -277,31 +277,6 @@
 )
 
 
-class BrickLayout
-  constructor: (@viewState, @numRows) ->
-    @noteRow = {} # uristr: row, t0, t1
-  addNote: (n) ->
-    @noteRow[n.uri.value] = {row: 0, t0: 0, t1: 0}
-    
-  setNoteSpan: (n, t0, t1) ->
-    @noteRow[n.uri.value].t0 = t0
-    @noteRow[n.uri.value].t1 = t1
-    @_recompute()
-  delNote: (n) ->
-    delete @noteRow[n.uri.value]
-  _recompute: ->
-    notesByWidth = _.sortBy([{dur: row.t1 - row.t0 + row.t0 * .0001, uri: u} for u, row of @noteRow], 'dur')
-    notesByWidth.reverse()
-    for n in notesByWidth
-      @noteRow[n.uri].row = 0
-    
-  rowBottom: (row) -> @viewState.rowsY() + 20 + 150 * row + 140
-  yForVFor: (n) ->
-    row = @noteRow[n.uri.value].row
-    rowBottom = @rowBottom(row)
-    rowTop = rowBottom - 140
-    (v) => rowBottom + (rowTop - rowBottom) * v      
-
 # plan: in here, turn all the notes into simple js objects with all
 # their timing data and whatever's needed for adjusters. From that, do
 # the brick layout. update only changing adjusters.
@@ -370,7 +345,6 @@
     
   onZoom: ->
     updateZoomFlattened = ->
-      log('updateZoomFlattened')
       @zoomFlattened = ko.toJS(@viewState.zoomSpec)
     ko.computed(updateZoomFlattened.bind(@))
 
@@ -418,7 +392,7 @@
     note = new Note(@, con, @project, @graph, @selection, uri, @setAdjuster, U(@song), @viewState, @brickLayout)
     # this must come before the first Note.draw
     @noteByUriStr.set(uri.value, note)
-    @brickLayout.addNote(note)
+    @brickLayout.addNote(note, note.onRowChange.bind(note))
     note.initWatchers()
 
   _delNote: (uriStr) ->
@@ -488,6 +462,7 @@
 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}")
@@ -534,19 +509,25 @@
       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 @uri.equals(@selection.hover())
+    if params.hover
       @_traceBorder(params.screenPts, 12, 0x888888)
-    @selection.selected().forEach (s) =>
-      if s.equals(@uri)
-        @_traceBorder(params.screenPts, 6, 0xff2900)
+    if params.selected
+      @_traceBorder(params.screenPts, 6, 0xff2900)
 
     shape = new PIXI.Polygon(params.screenPts)
     @graphics.beginFill(@_noteColor(params.effect), .313)
@@ -554,6 +535,8 @@
     @graphics.endFill()
 
     @_traceBorder(params.screenPts, 2, 0xffd900)
+
+    @_addMouseBindings()
                  
   update: ->
     if not @parentElem.isActiveNote(@uri)
@@ -569,8 +552,6 @@
 
     @redraw(params)
 
-    @_addMouseBindings()
-
     curveWidthCalc = () => @project.curveWidth(@worldPts)
     @_updateAdjusters(params.screenPts, @worldPts, curveWidthCalc,
                       params.yForV, @viewState.zoomInX, @song)
--- a/light9/web/timeline/viewstate.coffee	Sun Jun 03 04:51:43 2018 +0000
+++ b/light9/web/timeline/viewstate.coffee	Sun Jun 03 10:37:00 2018 +0000
@@ -30,7 +30,6 @@
     @maintainZoomLimitsAndScales() # before other handlers run
     
   maintainZoomLimitsAndScales: () ->
-    log('maintainZoomLimitsAndScales')
     # not for cursor updates
 
     if @zoomSpec.t1() < 0