Changeset - 53f751982ddf
[Not reviewed]
default
0 5 1
drewp@bigasterisk.com - 7 years ago 2018-04-26 05:40:12
drewp@bigasterisk.com
WIP polymer2 upgrade, timeline rewrite
Ignore-this: 73b86663c0dcb783c9c6e65f6be901a
6 files changed with 101 insertions and 106 deletions:
0 comments (0 inline, 0 general)
light9/web/edit-choice-demo.html
Show inline comments
 
new file 100644
 
<!doctype html>
 
<html>
 
  <head>
 
    <title></title>
 
    <meta charset="utf-8" />
 
    <script src="/lib/webcomponentsjs/webcomponents-hi-sd-ce.js"></script>
 
    <link rel="import" href="rdfdb-synced-graph.html">
 
    <link rel="import" href="edit-choice.html">
 
    <script src="/lib/N3.js-pull61/browser/n3-browser.js"></script>
 
      <script src="/lib/knockout/dist/knockout.js"></script>
 
      <script src="/lib/shortcut/index.js"></script>
 
      <script src="/lib/async/dist/async.js"></script>
 
      <script src="/lib/underscore/underscore-min.js"></script>
 
  </head>
 
  <body>
 
    <dom-bind>
 
      <template>
 
        <p>
 
          <rdfdb-synced-graph graph="{{graph}}"></rdfdb-synced-graph>
 
        </p>
 
        <p>
 
          edit-choice: <edit-choice graph="{{graph}}" uri="http://example.com/hello"></edit-choice>
 
        </p>
 
        <p>
 
          <a href="http://light9.bigasterisk.com/effect/spideredge" >this has a label</a>
 
      </template>
 
    </dom-bind>
 
  </body>
 
</html>
light9/web/edit-choice.coffee
Show inline comments
 
@@ -13,44 +13,47 @@ window.setupDrop = (senseElem, highlight
 
    
 
  senseElem.addEventListener 'dragend', (event) =>
 
    
 
  senseElem.addEventListener 'dragover', (event) =>
 
    event.preventDefault()
 
    event.dataTransfer.dropEffect = 'copy'
 
    highlight()
 

	
 
  senseElem.addEventListener 'dragenter', (event) =>
 
    highlight()
 
    
 
  senseElem.addEventListener 'dragleave', (event) =>
 
    unhighlight()
 
   
 
  senseElem.addEventListener 'drop', (event) ->
 
    event.preventDefault()
 
    uri = event.dataTransfer.getData('text/uri-list')
 

	
 
    pos = if coordinateOriginElem?
 
        root = coordinateOriginElem.getBoundingClientRect()
 
        $V([event.pageX - root.left, event.pageY - root.top])
 
      else
 
        null
 

	
 
    onDrop(uri, pos)
 
    try
 
      onDrop(uri, pos)
 
    catch e
 
      console.log(e)
 
    unhighlight()
 

	
 

	
 

	
 
Polymer
 
    is: "edit-choice",
 
    properties:
 
        graph: {type: Object, notify: true},
 
        uri: {type: String, notify: true},
 

	
 
    ready: ->
 
      @uri = null
 
      setupDrop @$.box, @$.box, null, (uri) =>
 
        @uri=uri
 
        @updateLabel()
 

	
 
    unlink: ->
 
      @uri = null
 

	
light9/web/lib/bower.json
Show inline comments
 
{
 
  "name": "3rd-party libs",
 
  "dependencies": {
 
    "polymer": "~1.4.0",
 
    "paper-slider": "PolymerElements/paper-slider#~1.0.11",
 
    "iron-ajax": "PolymerElements/iron-ajax#~1.2.0",
 
    "jquery": "^3.2.1",
 
    "polymer": "2.6.0",
 
    "paper-slider": "PolymerElements/paper-slider#~2.0.6",
 
    "iron-ajax": "PolymerElements/iron-ajax#~2.1.3",
 
    "jquery": "^3.3.1",
 
    "underscore": "~1.8.3",
 
    "jquery-ui": "~1.11.4",
 
    "QueryString": "http://unixpapa.com/js/QueryString.js",
 
    "knockout": "knockoutjs#^3.4.0",
 
    "knockout": "knockoutjs#^3.4.2",
 
    "sylvester": "~0.1.3",
 
    "d3": "https://github.com/d3/d3.git#e7194db33090a0afc06c77a959594361ffb949df",
 
    "rdflib.js": "https://github.com/linkeddata/rdflib.js.git#920e59fe37",
 
    "rdfstore": "https://github.com/antoniogarrote/rdfstore-js.git#b3f7c0c9c1da9b26261af0d4858722fa982411bb",
 
    "N3.js": "https://github.com/RubenVerborgh/N3.js.git#04f4e21f4ccb351587dc00a3f26340b28d4bb10f",
 
    "shortcut": "http://www.openjs.com/scripts/events/keyboard_shortcuts/shortcut.js",
 
    "async": "https://github.com/caolan/async.git#^1.5.2",
 
    "iron-resizable-behavior": "PolymerElements/iron-resizable-behavior#^1.0.3",
 
    "paper-radio-button": "PolymerElements/paper-radio-button#^1.2.2",
 
    "paper-button": "PolymerElements/paper-button#^1.0.12",
 
    "paper-dialog": "PolymerElements/paper-dialog#^1.0.4",
 
    "paper-radio-group": "PolymerElements/paper-radio-group#^1.2.2",
 
    "iron-resizable-behavior": "PolymerElements/iron-resizable-behavior#^2.1.0",
 
    "paper-radio-button": "PolymerElements/paper-radio-button#^2.1.0",
 
    "paper-button": "PolymerElements/paper-button#^2.1.0",
 
    "paper-dialog": "PolymerElements/paper-dialog#^2.1.0",
 
    "paper-radio-group": "PolymerElements/paper-radio-group#^2.1.0",
 
    "color": "https://github.com/One-com/one-color.git#^3.0.4",
 
    "paper-listbox": "PolymerElements/paper-listbox#1.1.3",
 
    "paper-item": "PolymerElements/paper-item#1.2.2",
 
    "paper-listbox": "PolymerElements/paper-listbox#2.1.0",
 
    "paper-item": "PolymerElements/paper-item#2.1.0",
 
    "paper-styles": "PolymerElements/paper-styles#^2.1.0",
 
    "isotope": "^3.0.4",
 
    "isotope-fit-columns": "^1.1.3",
 
    "jquery.columnizer": "https://github.com/adamwulf/Columnizer-jQuery-Plugin.git#^1.6.2"
 
  },
 
  "resolutions": {
 
    "paper-styles": "^1.1.4",
 
    "rdflib.js": "920e59fe37",
 
    "d3": "e7194db33090a0afc06c77a959594361ffb949df",
 
    "webcomponentsjs": "^0.7.24",
 
    "polymer": "^1.2.1",
 
    "jquery": "^3.2.1"
 
    "jquery": "^3.2.1",
 
    "webcomponentsjs": "^v1.1.0",
 
    "paper-radio-button": "^2.1.0",
 
    "iron-resizable-behavior": "^2.1.0",
 
    "polymer": "2.6.0"
 
  }
 
}
light9/web/resource-display.html
Show inline comments
 
@@ -33,48 +33,49 @@
 
          <paper-button dialog-dismiss>Cancel</paper-button>
 
          <paper-button dialog-confirm>OK</paper-button>
 
        </div>
 
      </paper-dialog>
 
      
 
    </template>
 
  </template>
 
  <script>
 
   Polymer({
 
       is: "resource-display",
 
       properties: {
 
           graph: { type: Object },
 
           uri: { type: String },
 
           label: { type: String },
 
           rename: { type: Boolean },
 
           minor: { type: Boolean },
 
           resClasses: { type: String, computed: '_resClasses(minor)', value: 'resource' },
 
           renameTo: { type: String, notify: true },
 
       },
 
       observers: ['onUri(graph, uri)'],
 
       _resClasses: function(minor) {
 
           return minor ? 'resource minor' : 'resource';
 
       },
 
       onUri: function(graph, uri) {
 
           if (!this.graph) return;
 
           this.graph.runHandler(this.setLabel.bind(this), `label ${this.uri}`);
 
       },
 
       setLabel: function() {
 
           if (!this.uri) {
 
               this.label = "<no uri>";
 
               return;
 
           }
 
           try {
 
               this.label = this.graph.stringValue(this.uri,
 
                                                   this.graph.Uri('rdfs:label'));
 
           } catch(e) {
 
               this.label = null;
 
           }
 
           if (!this.label) {
 
               this.label = this.uri.replace(/.*\//, '');
 
           }
 
       },
 
       onRename: function() {
 
           this.renameTo = this.label;
 
           this.querySelector("#renameDialog").open();
 
           this.querySelector("#renameTo").setSelectionRange(0, -1);
 
       },
 
       onRenameKey: function(ev) {
 
           if (ev.key == 'Enter') {
light9/web/timeline/timeline-elements.html
Show inline comments
 
@@ -8,137 +8,131 @@
 
<link rel="import" href="../edit-choice.html">
 

	
 

	
 
<!-- Whole editor- include this on your page.
 
     Most coordinates are relative to this element.
 
   -->
 
<dom-module id="light9-timeline-editor">
 
  <template>
 
    <style>
 
     :host {
 
         background: #444;
 
         display: flex;
 
         flex-direction: column;
 
         position: relative;
 
         border: 1px solid black;
 
         overflow: hidden;
 
     }
 
     light9-timeline-audio {
 
         width: 100%;
 
         height: 30px;
 
     }
 
     light9-timeline-time-zoomed {
 
         flex-grow: 1;
 
     }
 
     #coveredByDiagram {
 
         position: relative;
 
     }
 
     #dia, #adjusters, #cursorCanvas, #adjustersCanvas {
 
         position: absolute;
 
         left: 0; top: 0; right: 0; bottom: 0;
 
     }
 
     #debug {
 
      background: white;
 
      font-family: monospace;
 
      font-size: 125%;
 
      height: 15px;
 
     }
 
    </style>
 
    <div>
 
      <rdfdb-synced-graph graph="{{graph}}"></rdfdb-synced-graph>
 
      <light9-music id="music"
 
                    song="{{playerSong}}"
 
                    t="{{songTime}}"
 
                    playing="{{songPlaying}}"
 
                    duration="{{songDuration}}"></light9-music>
 
      timeline editor: song <edit-choice graph="{{graph}}" uri="{{song}}"></edit-choice>
 
      <label><input type="checkbox" checked="{{followPlayerSong::change}}" > follow player song choice</label>
 
    </div>
 
    <div id="debug">[[debug]]</div>
 
    <iron-ajax id="vidrefTime" url="/vidref/time" method="PUT" content-type="application/json"></iron-ajax>
 
    <light9-timeline-audio id="audio"
 
                           graph="{{graph}}"
 
                           show="{{show}}"
 
                           song="{{song}}"></light9-timeline-audio>
 
    <light9-timeline-time-zoomed id="zoomed"
 
                                 graph="{{graph}}"
 
                                 selection="{{selection}}"
 
                                 dia="{{dia}}"
 
                                 set-adjuster="{{setAdjuster}}"
 
                                 song="{{song}}"
 
                                 show="{{show}}"
 
                                 zoom="{{viewState.zoomSpec}}"
 
                                 zoom-in-x="{{zoomInX}}">
 
    </light9-timeline-time-zoomed>
 
    <light9-timeline-diagram-layer id="dia" selection="{{selection}}"></light9-timeline-diagram-layer>
 
    <light9-adjusters-canvas id="adjustersCanvas" set-adjuster="{{setAdjuster}}">
 
    </light9-adjusters-canvas>
 
    <light9-cursor-canvas id="cursorCanvas"></light9-cursor-canvas>
 
    <div id="coveredByDiagram">
 
      <light9-timeline-audio id="audio"
 
                             graph="{{graph}}"
 
                             show="{{show}}"
 
                             song="{{song}}"></light9-timeline-audio>
 
      <light9-timeline-time-zoomed id="zoomed"
 
                                   graph="{{graph}}"
 
                                   selection="{{selection}}"
 
                                   dia="{{dia}}"
 
                                   set-adjuster="{{setAdjuster}}"
 
                                   song="{{song}}"
 
                                   show="{{show}}"
 
                                   zoom="{{viewState.zoomSpec}}"
 
                                   zoom-in-x="{{zoomInX}}">
 
      </light9-timeline-time-zoomed>
 
      <light9-timeline-diagram-layer id="dia" selection="{{selection}}"></light9-timeline-diagram-layer>
 
      <light9-adjusters-canvas id="adjustersCanvas" set-adjuster="{{setAdjuster}}">
 
      </light9-adjusters-canvas>
 
      <light9-cursor-canvas id="cursorCanvas"></light9-cursor-canvas>
 
    </div>
 
  </template>
 
 
 
</dom-module>
 

	
 
<!-- the whole section that pans/zooms in time (most of the editor) -->
 
<dom-module id="light9-timeline-time-zoomed">
 
  <template>
 
    <style>
 
     :host {
 
         display: flex;
 
         height: 100%;
 
     }
 
     div {
 
         display: flex;
 
         flex-direction: column;
 
         height: 100%;
 
     }
 
     #rows.dragging {
 
         background: rgba(126, 52, 245, 0.0784);
 
         }
 
     light9-timeline-audio {
 
         width: 100%;
 
         height: 100px;
 
     }
 
     light9-timeline-graph-row {
 
         flex-grow: 1;
 
     }
 
    </style>
 
    <div id="top">
 
      <light9-timeline-time-axis id="time"></light9-timeline-time-axis>
 
      <light9-timeline-audio id="audio"
 
                             graph="{{graph}}"
 
                             song="{{song}}"
 
                             show="{{show}}"
 
                             zoom="{{zoomFlattened}}">
 
      </light9-timeline-audio>
 
      <div id="rows">
 
        <template is="dom-repeat" items="{{rows}}">
 
          <light9-timeline-graph-row graph="{{graph}}"
 
                                     selection="{{selection}}"
 
                                     dia="{{dia}}"
 
                                     set-adjuster="{{setAdjuster}}"
 
                                     song="{{song}}"
 
                                     zoom-in-x="{{zoomInX}}"
 
                                     row-index="{{item}}"
 
          >
 
          </light9-timeline-graph-row>
 
        </template>
 
      </div>
 
    </div>
 
  </template>
 
</dom-module>
 

	
 

	
 
<!--
 
     SVG or canvas that draws these:
 
       - background grids
 
       - zoom arcs
 
       - notes
 
     
 
     This element is not responsible for any hit detection. Things you click (rows,
 
     notes, adjusters, etc) are caught on their respective elements. (But is that
 
     wrong in the case of notes?)
 
   -->
 
<dom-module id="light9-timeline-diagram-layer">
 
  <template>
 
    <style>
 
      :host {
 
      }
 
      svg {
 
      width: 100%;
 
      height: 100%;
 
@@ -191,61 +185,48 @@
 
  <template>
 
    <style>
 
     #canvas, :host {
 
         pointer-events: none;
 
     }
 
    </style>
 
    <canvas id="canvas"></canvas>
 
  </template>
 
</dom-module>
 
      
 

	
 
<!-- seconds labels -->
 
<dom-module id="light9-timeline-time-axis">
 
  <template>
 
    <style>
 
     div {
 
         width: 100%;
 
         height: 31px;
 
     }
 
    </style>
 
    <div></div>
 
  </template>
 
</dom-module>
 

	
 
<!-- one row of notes -->
 
<dom-module id="light9-timeline-graph-row">
 
  <template>
 
    <style>
 
     :host {
 
         border-top: 1px solid black;
 
         display: flex;
 
     }
 
    </style>
 
    <!-- light9-timeline-note repeated here -->
 
  </template>
 
</dom-module>
 

	
 
<!-- One trapezoid note shape in a row.
 
     This element has the right Y coords.
 
     We compute X coords from the zoom setting.
 
     diagram-layer draws the note body. -->
 
<dom-module id="light9-timeline-note">
 
  <template>
 
    <style>
 
     :host {
 
         display: block;
 
         background: green;
 
         /* outline: 2px solid red; */
 
     }
 
    </style>
 
    <light9-timeline-note-inline-attrs rect="{{inlineRect}}"
 
                                       graph="{{graph}}"
 
                                       selection="{{selection}}"
 
                                       song="{{song}}"
 
                                       uri="{{uri}}"
 
                                       effect="{{effect}}"
 
    >
 
    </light9-timeline-note-inline-attrs>
 
  </template>
 
</dom-module>
 

	
 
@@ -279,31 +260,31 @@
 
         padding: 3px;
 
         z-index: 2;
 
     }
 
    </style>
 
    <div id="top" style$="left: [[rect.left]]px; top: [[rect.top]]px; width: [[rect.width]]px; height: [[rect.height]]px; display: [[rect.display]]">
 
      <div>note [[noteLabel]] <button on-click="onDel">del</button></div>
 
      <table>
 
        <tr><th>effect:</th><td><edit-choice graph="{{graph}}" uri="{{effect}}"></edit-choice></td></tr>
 
        <tr><th>colorScale:</th><td>
 
          <light9-color-picker color="{{colorScale}}"></light9-color-picker>
 
        </td></tr>
 
      </table>
 
    </div>
 
  </template>
 
</dom-module>
 

	
 
<script src="/lib/sylvester/sylvester.js"></script>
 
<script src="/lib/d3/build/d3.min.js"></script>
 

	
 
<!-- version with https://github.com/RubenVerborgh/N3.js/pull/61 -->
 
<script src="/lib/N3.js-pull61/browser/n3-browser.js"></script>
 
<!-- master version -->
 
<xxscript src="/lib/N3.js/browser/n3-browser.js"></script>
 
  
 
<script src="/lib/knockout/dist/knockout.debug.js"></script>
 
<script src="/lib/knockout/dist/knockout.js"></script>
 
<script src="/lib/shortcut/index.js"></script>
 
<script src="/lib/async/dist/async.js"></script>
 
<script src="/lib/underscore/underscore-min.js"></script>
 
<script src="adjustable.js"></script>
 
<script src="drawing.js"></script>
 
<script src="timeline.js"></script>
light9/web/timeline/timeline.coffee
Show inline comments
 
log = console.log
 
RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'
 
Drawing = window.Drawing
 
ROW_COUNT = 7
 

	
 
# polymer dom-repeat is happy to shuffle children by swapping their
 
# attribute values, and it's hard to correctly setup/teardown your
 
# side effects if your attributes are changing before the detach
 
# call. This alternative to dom-repeat never reassigns
 
# attributes. But, it can't set up property bindings.
 
updateChildren = (parent, newUris, makeChild) ->
 
  childUris = []
 
  childByUri = {}
 
  for e in parent.children
 
    childUris.push(e.uri)
 
    childByUri[e.uri] = e
 

	
 
  for uri in _.difference(childUris, newUris)
 
    childByUri[uri].detached()
 
    ko.removeNode(childByUri[uri])
 
  for uri in _.difference(newUris, childUris)
 
    parent.appendChild(makeChild(uri))
 

	
 

	
 
Polymer
 
  is: 'light9-timeline-editor'
 
  behaviors: [ Polymer.IronResizableBehavior ]
 
  properties:
 
    viewState: { type: Object }
 
    debug: {type: String}
 
    graph: {type: Object, notify: true}
 
    setAdjuster: {type: Function, notify: true}
 
    playerSong: {type: String, notify: true}
 
    followPlayerSong: {type: Boolean, notify: true, value: true}
 
    song: {type: String, notify: true}
 
    show: {value: 'http://light9.bigasterisk.com/show/dance2017'}
 
    songTime: {type: Number, notify: true, observer: '_onSongTime'}
 
    songDuration: {type: Number, notify: true, observer: '_onSongDuration'}
 
    songPlaying: {type: Boolean, notify: true}
 
    fullZoomX: {type: Object, notify: true}
 
    zoomInX: {type: Object, notify: true}
 
    selection: {type: Object, notify: true}
 
  width: ko.observable(1)
 
  listeners:
 
    'iron-resize': '_onIronResize'
 
  observers: [
 
    'setSong(playerSong, followPlayerSong)'
 
@@ -266,58 +248,71 @@ Polymer
 

	
 
    @setAdjuster('zoom-pan', => new AdjustableFloatObservable({
 
      observable: panObs
 
      emptyBox: true
 
      # fullzoom is not right- the sides shouldn't be able to go
 
      # offscreen
 
      getTarget: () => $V([@fullZoomX(panObs()), yMid()])
 
      getSuggestedTargetOffset: () => $V([0, 0])
 
      getValueForPos: valForPos
 
      }))
 
      
 

	
 
# 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.
 
Polymer
 
  is: 'light9-timeline-time-zoomed'
 
  behaviors: [ Polymer.IronResizableBehavior ]
 
  properties:
 
    graph: { type: Object, notify: true }
 
    selection: { type: Object, notify: true }
 
    dia: { type: Object, notify: true }
 
    song: { type: String, notify: true }
 
    zoomInX: { type: Object, notify: true }
 
    rows: { value: [0...ROW_COUNT] }
 
    zoom: { type: Object, notify: true, observer: 'onZoom' } # viewState.zoomSpec
 
    zoomFlattened: { type: Object, notify: true }
 
  observers: [
 
    'onGraph(graph, dia, setAdjuster, song, zoomInX)'
 
  ]
 
  onZoom: ->
 
    updateZoomFlattened = ->
 
      log('updateZoomFlattened')
 
      @zoomFlattened = ko.toJS(@zoom)
 
    ko.computed(updateZoomFlattened.bind(@))
 
  ready: ->
 

	
 
  onGraph: ->
 
    U = (x) => @graph.Uri(x)
 
    log('assign rows',@song)
 

	
 
    for uri in _.sortBy(@graph.objects(@song, U(':note')), 'uri')
 
      #should only make new ones
 
      child = new Note(@graph, @selection, @dia, uri, @setAdjuster, @song, @zoomInX)
 
      log('note ',uri)
 
    
 
    @rows = (new NoteRow(@graph, @dia, @song, @zoomInX, @noteUris, i, @selection) for i in [0...ROW_COUNT])
 

	
 
  attached: ->
 
    root = @closest('light9-timeline-editor')
 

	
 
  onDrop: (effect, pos) ->
 
    U = (x) => @graph.Uri(x)
 

	
 
    return unless effect and effect.match(/^http/)
 

	
 
    # we could probably accept some initial overrides right on the
 
    # effect uri, maybe as query params
 

	
 
    if not @graph.contains(effect, RDF + 'type', U(':Effect'))
 
      if @graph.contains(effect, RDF + 'type', U(':LightSample'))
 
        effect = @makeEffect(effect)
 
      else
 
        log("drop #{effect} is not an effect")
 
        return
 

	
 
    dropTime = @zoomInX.invert(pos.e(1))
 
    @makeNewNote(effect, dropTime)
 

	
 
  makeEffect: (uri) ->
 
    U = (x) => @graph.Uri(x)
 
    effect = U(uri + '/effect')
 
@@ -368,101 +363,85 @@ Polymer
 
    pointQuads = []
 

	
 
    desiredWidthX = @offsetWidth * .3
 
    desiredWidthT = @zoomInX.invert(desiredWidthX) - @zoomInX.invert(0)
 
    desiredWidthT = Math.min(desiredWidthT, @zoom.duration() - dropTime)
 
    
 
    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)
 

	
 
Polymer
 
  is: "light9-timeline-time-axis",
 
  # for now since it's just one line calling dia,
 
  # light9-timeline-editor does our drawing work.
 

	
 

	
 
Polymer
 
  is: 'light9-timeline-graph-row'
 
  behaviors: [ Polymer.IronResizableBehavior ]
 
  properties:
 
    graph: { type: Object, notify: true }
 
    dia: { type: Object, notify: true }
 
    song:  { type: String, notify: true }
 
    zoomInX: { type: Object, notify: true }
 
    noteUris: { type: Array, notify: true }
 
    rowIndex: { type: Object, notify: true }
 
    selection: { type: Object, notify: true }
 
class NoteRow
 
  constructor: (@graph, @dia, @song, @zoomInX, @noteUris, @rowIndex, @selection) ->
 
    @graph.runHandler(@update.bind(@), "row notes #{@rowIndex}")
 

	
 
  observers: [
 
    'onGraph(graph, dia, setAdjuster, song, zoomInX)'
 
    'observedUpdate(graph, song, rowIndex)'
 
    'onZoom(zoomInX)'
 
    ]
 
  onGraph: ->
 
    @graph.runHandler(@update.bind(@), "row notes #{@rowIndex}")
 

	
 

	
 
  observedUpdate: (graph, song, rowIndex) ->
 
    @update() # old behavior
 
    #@graph.runHandler(@update.bind(@), "row notes #{@rowIndex}")
 

	
 
  update: (patch) ->
 
    U = (x) => @graph.Uri(x)
 

	
 
    notesForThisRow = []
 
    i = 0
 
    for n in _.sortBy(@graph.objects(@song, U(':note')), 'uri')
 
      if (i % ROW_COUNT) == @rowIndex
 
        notesForThisRow.push(n)
 
      i++
 

	
 
    updateChildren @, notesForThisRow, (newUri) =>
 
      child = document.createElement('light9-timeline-note')
 
      child.graph = @graph
 
      child.selection = @selection
 
      child.dia = @dia
 
      child.uri = newUri
 
      child.setAdjuster = @setAdjuster
 
      child.song = @song # could change, but all the notes will be rebuilt
 
      child.zoomInX = @zoomInX # missing binding; see onZoom
 
      return child      
 
    for newUri in notesForThisRow
 
      #should only make new ones
 
      child = new Note(@graph, @selection, @dia, newUri, @setAdjuster, @song, @zoomInX)
 

	
 
  onZoom: ->
 
    for e in @children
 
      e.zoomInX = @zoomInX
 

	
 

	
 
Polymer
 
class Note
 
  constructor: (@graph, @selection, @dia, @uri, @setAdjuster, @song, @zoomInX)->0
 
  is: 'light9-timeline-note'
 
  behaviors: [ Polymer.IronResizableBehavior ]
 
  listeners: 'iron-resize': 'update'
 
  listeners: 'iron-resize': 'update' #move to parent elem
 
  properties:
 
    graph: { type: Object, notify: true }
 
    selection: { type: Object, notify: true }
 
    dia: { type: Object, notify: true }
 
    uri: { type: String, notify: true }
 
    zoomInX: { type: Object, notify: true }
 
    setAdjuster: {type: Function, notify: true }
 
    inlineRect: { type: Object, notify: true }
 
    song: { type: String, notify: true }
 
  observers: [
 
    'onUri(graph, dia, uri, zoomInX, setAdjuster, song)'
 
    'update(graph, dia, uri, zoomInX, setAdjuster, song)'
 
    ]
 
  ready: ->
 
    @adjusterIds = {} # id : true
 

	
 
  detached: ->
 
    log('detatch', @uri)
 
    @dia.clearNote(@uri)
 
    @isDetached = true
 
    @clearAdjusters()
 

	
 
  clearAdjusters: ->
 
    for i in Object.keys(@adjusterIds)
0 comments (0 inline, 0 general)