Changeset - e06c2c105035
[Not reviewed]
default
0 9 1
Drew Perttula - 7 years ago 2018-05-14 02:10:05
drewp@bigasterisk.com
workaround for coffee issue with static getters. polymer wasn't seeing my attributes at all
Ignore-this: 192b2826e728db8b7ca6cfb67609241e
10 files changed with 88 insertions and 69 deletions:
0 comments (0 inline, 0 general)
light9/web/coffee_element.coffee
Show inline comments
 
new file 100644
 
# Polymer seems to need static getters for 'observers' and
 
# 'listeners', not just static attributes, though I don't know how it
 
# can even tell the difference.
 
#
 
# This workaround is to use names like '@getter_properties' in the
 
# class then register with this function that fixes them.
 
# 
 
# Also see http://coffeescript.org/#unsupported-get-set
 
window.coffeeElementSetup = (cls) ->
 
  for attr in ['properties', 'observers', 'listeners']
 
    val = cls['getter_' + attr]
 
    if val?
 
      do (val) ->
 
        Object.defineProperty(cls, attr, {get: ( -> val)})  
 
  customElements.define(cls.is, cls)
light9/web/edit-choice.coffee
Show inline comments
 
@@ -39,23 +39,22 @@ window.setupDrop = (senseElem, highlight
 
    catch e
 
      console.log(e)
 
    unhighlight()
 

	
 

	
 

	
 
class EditChoice extends Polymer.Element
 
coffeeElementSetup(class EditChoice extends Polymer.Element
 
    @is: "edit-choice",
 
    @properties:
 
    @getter_properties:
 
        graph: {type: Object, notify: true},
 
        uri: {type: String, notify: true},
 

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

	
 
    unlink: ->
 
      @uri = null
 

	
 
customElements.define(EditChoice.is, EditChoice)
 
\ No newline at end of file
 
)
light9/web/edit-choice.html
Show inline comments
 
@@ -25,8 +25,9 @@
 
    </style>
 
    <div id="box">
 
      <resource-display graph="{{graph}}" uri="{{uri}}" rename></resource-display>
 
      <button on-click="unlink">Unlink</button>
 
    </div>
 
  </template>
 
  <script src="coffee_element.js"></script>
 
  <script src="edit-choice.js"></script>
 
</dom-module>
light9/web/light9-music.coffee
Show inline comments
 
log = console.log
 

	
 
# port of light9/curvecalc/musicaccess.py
 
Polymer
 
  is: "light9-music",
 
  properties:
 
coffeeElementSetup(class Music extends Polymer.Element
 
  @is: "light9-music",
 
  @getter_properties:
 
    status: { type: String, notify: true }
 
    statusTitle: { type: String, notify: true }
 
    turboSign: { type: String, notify: true }
 
    
 
    duration: { type: Number, notify: true }
 
    song: { type: String, notify: true }
 
    # It does not yet work to write back to the playing/t
 
    # properties. See seekPlayOrPause.
 
    playing: { type: Boolean, notify: true }
 
    t: { type: Number, notify: true }
 
    
 
  ready: ->
 
    super.ready()
 
    @turboUntil = 0
 
    @$.getTime.addEventListener('response', @onResponse.bind(@))
 
    @$.getTime.addEventListener 'error', (e) =>
 
      req = @$.getTime.lastRequest
 
      @status = "✘"
 
      @statusTitle = "GET "+req.url+ " -> " + req.status + " " + req.statusText
 
      setTimeout(@poll.bind(@), 2000)
 
    @poll()
 
    setInterval(@estimateTimeLoop.bind(@), 30)
 

	
 
  onError: (e) ->
 
    req = @$.getTime.lastRequest
 
    @status = "✘"
 
    @statusTitle = "GET "+req.url+ " -> " + req.status + " " + req.statusText
 
    setTimeout(@poll.bind(@), 2000)
 
    
 
  estimateTimeLoop: ->
 
    if @playing
 
      @t = @remoteT + (Date.now() - @remoteAsOfMs) / 1000
 
    else
 
      @t = @remoteT
 
    
 
  poll: ->
 
    if not @$?.getTime?
 
      setTimeout(@poll.bind(@), 200)
 
      return
 
    clearTimeout(@nextPoll) if @nextPoll
 
    @$.getTime.generateRequest()
 
    @status = "♫"
 
    
 
  onResponse: ->
 
    @status = " "
 
@@ -62,7 +66,8 @@ Polymer
 
  seekPlayOrPause: (t) ->
 
    @$.seek.body = {t: t}
 
    @$.seek.generateRequest()
 
    
 
    @turboUntil = Date.now() + 1000
 
    @poll()
 
    
 
)
 

	
light9/web/light9-music.html
Show inline comments
 
<link rel="import" href="/lib/polymer/polymer.html">
 
<link rel="import" href="/lib/polymer/polymer-element.html">
 
<link rel="import" href="/lib/iron-ajax/iron-ajax.html">
 

	
 
<!-- remote control of ascoltami -->
 
<dom-module id="light9-music">
 
  <template>
 
    <style>
 
@@ -11,15 +11,16 @@
 
         background: black;
 
         color: white;
 
         border: 1px solid #2782ad;
 
         font-size: 12px;
 
     }
 
    </style>
 
    <iron-ajax id="getTime" url="/ascoltami/time"></iron-ajax>
 
    <iron-ajax id="getTime" on-response="onResponse" on-error="onError" url="/ascoltami/time"></iron-ajax>
 
    <iron-ajax id="seek"
 
               method="POST"
 
               url="/ascoltami/seekPlayOrPause"
 
               content-type="application/json"></iron-ajax>
 
    <span>[[status]][[turboSign]]</span>
 
  </template>
 
  <script src="coffee_element.js"></script>
 
  <script src="light9-music.js"></script>
 
</dom-module>
light9/web/timeline/adjusters.coffee
Show inline comments
 
log = console.log
 
Drawing = window.Drawing
 

	
 

	
 
class AdjustersCanvas extends Polymer.Element
 
coffeeElementSetup(class AdjustersCanvas extends Polymer.mixinBehaviors([Polymer.IronResizableBehavior], Polymer.Element)
 
  @is: 'light9-adjusters-canvas'
 
  @behaviors: [ Polymer.IronResizableBehavior ]
 
  @properties:
 
  @getter_properties:
 
    adjs: { type: Object, notify: true }, # adjId: Adjustable
 
  @observers: [
 
  @getter_observers: [
 
    'updateAllCoords(adjs)'
 
  ]
 
  @listeners:
 
  @getter_listeners:
 
    'iron-resize': 'resizeUpdate'
 
  connectedCallback: ->
 
    super.connectedCallback()
 
    @adjs = {}
 
    @ctx = @$.canvas.getContext('2d')
 

	
 
@@ -155,8 +154,7 @@ class AdjustersCanvas extends Polymer.El
 

	
 
    # coords from a center that's passed in
 
    # # special layout for the thaeter ones with middinh 
 
    # l/r arrows
 
    # mouse arrow cursor upon hover, and accent the hovered adjuster
 
    # connector
 

	
 
customElements.define(AdjustersCanvas.is, AdjustersCanvas)
 
\ No newline at end of file
 
)
 
\ No newline at end of file
light9/web/timeline/cursor_canvas.coffee
Show inline comments
 

	
 
Polymer
 
  is: 'light9-cursor-canvas'
 
  behaviors: [ Polymer.IronResizableBehavior ]
 
  listeners: 'iron-resize': 'update'
 
  properties:
 
coffeeElementSetup(class CursorCanvas extends Polymer.mixinBehaviors([Polymer.IronResizableBehavior], Polymer.Element)
 
  @is: 'light9-cursor-canvas'
 
  @getter_properties:
 
    viewState: { type: Object, notify: true, observer: "onViewState" }
 
  ready: ->
 
  @getter_listeners: 'iron-resize': 'update'
 
  connectedCallback: ->
 
    super.connectedCallback()
 
    @mouseX = 0
 
    @mouseY = 0
 
    @cursorPath = null
 
    @ctx = @$.canvas.getContext('2d')
 

	
 
  onViewState: ->
 
@@ -64,7 +63,7 @@ Polymer
 
      
 
      @ctx.strokeStyle = '#ff0303'
 
      @ctx.lineWidth = 3
 
      @ctx.beginPath()
 
      Drawing.line(@ctx, @cursorPath.bot0, @cursorPath.bot1, '#ff0303', '3px')
 
      @ctx.stroke()
 
    
 
\ No newline at end of file
 
)
 
\ No newline at end of file
light9/web/timeline/inline-attrs.coffee
Show inline comments
 
log = console.log
 

	
 
class InlineAttrs extends Polymer.Element
 
coffeeElementSetup(class InlineAttrs extends Polymer.Element
 
  @is: "light9-timeline-note-inline-attrs"
 
  @properties:
 
  @getter_properties:
 
    graph: { type: Object, notify: true }
 
    song: { type: String, notify: true }
 
    uri: { type: String, notify: true }  # the Note
 
    rect: { type: Object, notify: true }
 
    effect: { type: String, notify: true }
 
    colorScale: { type: String, notify: true }
 
    noteLabel: { type: String, notify: true }
 
    selection: { type: Object, notify: true }
 
  @observers: [
 
  @getter_observers: [
 
    'addHandler(graph, uri)'
 
    'onColorScale(graph, uri, colorScale)'
 
    ]
 
  displayed: ->
 
    @querySelector('light9-color-picker').displayed()
 
  onColorScale: ->
 
@@ -69,7 +69,7 @@ class InlineAttrs extends Polymer.Elemen
 
      @colorScale = '#ffffff'
 
    #console.timeEnd('attrs update')
 

	
 

	
 
  onDel: ->
 
    deleteNote(@graph, @song, @uri, @selection)
 
customElements.define(InlineAttrs.is, InlineAttrs)
 
)
light9/web/timeline/timeline-elements.html
Show inline comments
 
@@ -264,11 +264,12 @@
 
<script src="/lib/sylvester/sylvester.js"></script>
 
<script src="/lib/underscore/underscore-min.js"></script>
 
<script src="/node_modules/d3/dist/d3.min.js"></script>
 
<script src="/node_modules/n3/n3-browser.js"></script> 
 
<script src="/node_modules/pixi.js/dist/pixi.min.js"></script>
 

	
 
<script src="../coffee_element.js"></script>
 
<script src="adjustable.js"></script>
 
<script src="adjusters.js"></script>
 
<script src="drawing.js"></script>
 
<script src="timeline.js"></script>
 
<script src="cursor_canvas.js"></script>
light9/web/timeline/timeline.coffee
Show inline comments
 
@@ -178,42 +178,43 @@ class ViewState
 
        setTimeout(gotoStep, delay)
 
        lastTime = delay
 
    setTimeout(=>
 
        @zoomSpec.t1(newT1)
 
        @zoomSpec.t2(newT2)
 
      , lastTime + 10)  
 

	
 
    
 
class TimelineEditor extends Polymer.mixinBehaviors([Polymer.IronResizableBehavior], Polymer.Element)
 
coffeeElementSetup(class TimelineEditor extends Polymer.mixinBehaviors([Polymer.IronResizableBehavior], Polymer.Element)
 
  @is: 'light9-timeline-editor'
 
  @properties:
 
  @getter_properties:
 
    viewState: { type: Object }
 
    debug: {type: String}
 
    graph: {type: Object, notify: true}
 
    project: {type: Object}
 
    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'}
 
    songTime: {type: Number, notify: true}
 
    songDuration: {type: Number, notify: true}
 
    songPlaying: {type: Boolean, notify: true}
 
    selection: {type: Object, notify: true}
 
  @observers: [
 
  @getter_observers: [
 
    'setSong(playerSong, followPlayerSong)',
 
    'onGraph(graph)',
 
    ]
 
    
 
    '_onSongDuration(songDuration, viewState)',
 
    '_onSongTime(songTime, viewState)',
 
  ]
 
  connectedCallback: ->
 
    super.connectedCallback()
 
    
 
    ko.options.deferUpdates = true;
 
    
 
    @dia = @$.dia
 
    
 

	
 
     
 
    @selection = {hover: ko.observable(null), selected: ko.observable([])}
 

	
 
    window.debug_zoomOrLayoutChangedCount = 0
 
    window.debug_adjUpdateDisplay = 0
 
    
 
    @viewState = new ViewState()
 
@@ -370,42 +371,31 @@ class TimelineEditor extends Polymer.mix
 
      # fullzoom is not right- the sides shouldn't be able to go
 
      # offscreen
 
      getTarget: () => $V([@fullZoomX(panObs()), yMid()])
 
      getSuggestedTargetOffset: () => $V([0, 0])
 
      getValueForPos: valForPos
 
      }))
 
      
 
customElements.define(TimelineEditor.is, TimelineEditor)
 
)
 

	
 

	
 
# 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.
 
class TimeZoomed extends Polymer.mixinBehaviors([Polymer.IronResizableBehavior], Polymer.Element)
 
coffeeElementSetup(class TimeZoomed extends Polymer.mixinBehaviors([Polymer.IronResizableBehavior], Polymer.Element)
 
  @is: 'light9-timeline-time-zoomed'
 
  @behaviors: [ Polymer.IronResizableBehavior ]
 
  @properties:
 
  @getter_properties:
 
    graph: { type: Object, notify: true }
 
    project: { type: Object }
 
    selection: { type: Object, notify: true }
 
    dia: { type: Object, notify: true }
 
    song: { type: String, notify: true }
 
    viewState: { type: Object, notify: true }
 
  @observers: [
 
  @getter_observers: [
 
    'onGraph(graph, setAdjuster, song, viewState, project)',
 
    'onZoom(viewState)',
 
  ]
 
  update: ->
 
    @renderer.resize(@clientWidth, @clientHeight)
 
    @renderer.render(@stage)
 

	
 
  onZoom: ->
 
    updateZoomFlattened = ->
 
      log('updateZoomFlattened')
 
      @zoomFlattened = ko.toJS(@viewState.zoomSpec)
 
    ko.computed(updateZoomFlattened.bind(@))
 

	
 
  constructor: ->
 
    super()
 
    @stage = new PIXI.Container()
 
    
 
    @renderer = PIXI.autoDetectRenderer({
 
         backgroundColor: 0xff6060,
 
@@ -416,14 +406,25 @@ class TimeZoomed extends Polymer.mixinBe
 
     
 
    @addEventListener('iron-resize', @update.bind(@))
 
    @update()
 
    
 
    @$.rows.appendChild(@renderer.view);
 
  
 
  update: ->
 
    @renderer.resize(@clientWidth, @clientHeight)
 
    @renderer.render(@stage)
 

	
 
  onZoom: ->
 
    updateZoomFlattened = ->
 
      log('updateZoomFlattened')
 
      @zoomFlattened = ko.toJS(@viewState.zoomSpec)
 
    ko.computed(updateZoomFlattened.bind(@))
 
  
 
  onGraph: ->
 
    @graph.runHandler(@gatherNotes.bind(@), 'zoom notes')
 
    
 
  gatherNotes: ->
 
    U = (x) => @graph.Uri(x)
 

	
 
    log('assign rows',@song, 'graph has', @graph.quads().length)
 
    graphics = new PIXI.Graphics({nativeLines: true})
 

	
 
@@ -473,38 +474,37 @@ class TimeZoomed extends Polymer.mixinBe
 
    dropTime = @viewState.zoomInX.invert(pos.e(1))
 

	
 
    desiredWidthX = @offsetWidth * .3
 
    desiredWidthT = @viewState.zoomInX.invert(desiredWidthX) - @viewState.zoomInX.invert(0)
 
    desiredWidthT = Math.min(desiredWidthT, @zoom.duration() - dropTime)
 
    @project.makeNewNote(effect, dropTime, desiredWidthT)
 
        
 
customElements.define(TimeZoomed.is, TimeZoomed)
 
)
 

	
 

	
 
class TimeAxis extends Polymer.Element
 
coffeeElementSetup(class TimeAxis extends Polymer.Element
 
  @is: "light9-timeline-time-axis",
 
  @properties:
 
  @getter_properties:
 
    viewState: { type: Object, notify: true, observer: "onViewState" }
 
  onViewState: ->
 
    ko.computed =>
 
      dependOn = [@viewState.zoomSpec.t1(), @viewState.zoomSpec.t2()]
 
      pxPerTick = 50
 
      axis = d3.axisTop(@viewState.zoomInX).ticks(@viewState.width() / pxPerTick)
 
      d3.select(@$.axis).call(axis)
 
)
 

	
 
customElements.define(TimeAxis.is, TimeAxis)
 

	
 
class NoteRow
 
  constructor: (@graph, @dia, @song, @zoomInX, @noteUris, @rowIndex, @selection) ->
 
    @graph.runHandler(@update.bind(@), "row notes #{@rowIndex}")
 

	
 
  observers: [
 
    'observedUpdate(graph, song, rowIndex)'
 
    'onZoom(zoomInX)'
 
    ]
 

	
 

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

	
 
  update: (patch) ->
 
    U = (x) => @graph.Uri(x)
 
@@ -693,16 +693,16 @@ class Note
 
      $V([0, 30])
 
    else
 
      $V([0, -30])
 
    
 
  
 
  
 
class DiagramLayer extends Polymer.Element
 
coffeeElementSetup(class DiagramLayer extends Polymer.Element
 
  # note boxes. 
 
  @is: 'light9-timeline-diagram-layer'
 
  @properties: {
 
  @getter_properties: {
 
    selection: {type: Object, notify: true}
 
  }
 
  connectedCallback: ->
 
    super.connectedCallback()
 
    @elemById = {}
 

	
 
@@ -791,7 +791,7 @@ class DiagramLayer extends Polymer.Eleme
 
      elem.setAttribute('class', classes)
 
    
 
    #elem = @getOrCreateElem(uri+'/label', 'noteLabels', 'text', {style: "font-size:13px;line-height:125%;font-family:'Verana Sans';text-align:start;text-anchor:start;fill:#000000;"})
 
    #elem.setAttribute('x', curvePts[0].e(1)+20)
 
    #elem.setAttribute('y', curvePts[0].e(2)-10)
 
    #elem.innerHTML = effectLabel;
 
customElements.define(DiagramLayer.is, DiagramLayer)
 
\ No newline at end of file
 
)
 
\ No newline at end of file
0 comments (0 inline, 0 general)