Changeset - 92104dcd33e2
[Not reviewed]
default
0 4 0
Drew Perttula - 7 years ago 2018-05-19 23:13:55
drewp@bigasterisk.com
finish mouse event routing. inlineAttrs display again.
Ignore-this: 5e5438f724a868ac12905a77e054d55
4 files changed with 72 insertions and 97 deletions:
0 comments (0 inline, 0 general)
light9/web/timeline/inline-attrs.coffee
Show inline comments
 
@@ -2,25 +2,33 @@ log = console.log
 

	
 
coffeeElementSetup(class InlineAttrs extends Polymer.Element
 
  @is: "light9-timeline-note-inline-attrs"
 
  @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 }
 
    config: { type: Object } # just for setup
 
    uri: { type: Object, notify: true }  # the Note
 
    effect: { type: Object, notify: true }
 
    colorScale: { type: String, notify: true }
 
    noteLabel: { type: String, notify: true }
 
    selection: { type: Object, notify: true }
 
  @getter_observers: [
 
    'addHandler(graph, uri)'
 
    'onColorScale(graph, uri, colorScale)'
 
    '_onConfig(config)'
 
    ]
 
  _onConfig: ->
 
    @uri = @config.uri
 
    for side in ['top', 'left', 'width', 'height']
 
      @.style[side] = @config[side] + 'px'
 

	
 
  displayed: ->
 
    @querySelector('light9-color-picker').displayed()
 
    
 
  onColorScale: ->
 
    return
 
    U = (x) => @graph.Uri(x)
 
    if @colorScale == @colorScaleFromGraph
 
      return
 
    @editAttr(@song, @uri, U(':colorScale'), @graph.Literal(@colorScale))
 

	
 
  editAttr: (song, note, attr, value) ->
 
@@ -45,12 +53,13 @@ coffeeElementSetup(class InlineAttrs ext
 
        quad(setting, U(':effectAttr'), attr)
 
        quad(setting, U(':value'), value)
 
        ]}
 
      @graph.applyAndSendPatch(patch)
 
    
 
  addHandler: ->
 
    return
 
    @graph.runHandler(@update.bind(@), "update inline attrs #{@uri}")
 
    
 
  update: ->
 
    #console.time('attrs update')
 
    U = (x) => @graph.Uri(x)
 
    @effect = @graph.uriValue(@uri, U(':effectClass'))
light9/web/timeline/inline-attrs.html
Show inline comments
 
@@ -3,28 +3,31 @@
 
<link rel="import" href="../edit-choice.html">
 

	
 
<!-- sometimes we draw attrs within the shape of a note. -->
 
<dom-module id="light9-timeline-note-inline-attrs">
 
  <template>
 
    <style>
 
     #top {
 
     :host {
 
         position: absolute;
 

	
 
         display: block;
 
         overflow: hidden;
 
         background: rgba(19, 19, 19, 0.65);
 
         border-radius: 6px;
 
         border: 1px solid #313131;
 
         padding: 3px;
 
         z-index: 2;
 
         color: white;
 
     }
 
    </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>
 
  <script src="inline-attrs.js"></script>
 
</dom-module>
light9/web/timeline/timeline-elements.html
Show inline comments
 
@@ -116,66 +116,18 @@
 
                             song="{{song}}"
 
                             show="{{show}}"
 
                             zoom="{{zoomFlattened}}">
 
      </light9-timeline-audio>
 
    </div>
 
    <div id="rows"></div>
 
    <template is="dom-repeat" items="{{inlineAttrConfigs}}">
 
      <light9-timeline-note-inline-attrs graph="{{graph}}"
 
                                         song="{{song}}"
 
                                         config="{{item}}"
 
      ></light9-timeline-note-inline-attrs>
 
  </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 {
 
         pointer-events: none;
 
     }
 
     svg {
 
         pointer-events: none;
 
         width: 100%;
 
         height: 100%;
 
     }
 
     #notes > path {
 
         stroke:#000000;
 
         stroke-width:1.5;
 
     }
 
     #notes > path.hover {
 
         stroke-width: 1.5;
 
         stroke: #888;
 
     }
 
     #notes > path.selected {
 
         stroke-width: 5;
 
         stroke: red;
 
     }
 
    </style>
 
    <svg xmlns="http://www.w3.org/2000/svg"
 
         xmlns:svg="http://www.w3.org/2000/svg"
 
         xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" >
 
      <g id="layer1">
 
        <text
 
            xml:space="preserve"
 
            style="font-size:13px;line-height:125%;font-family:'Verana Sans';-inkscape-font-specification:'Verana Sans';text-align:start;text-anchor:start;fill:#000000;"
 
            x="-338.38403"
 
            y="631.3988"
 
            id="text4290"
 
            sodipodi:linespacing="125%" ><tspan sodipodi:role="line" id="tspan4292" x="-338.38403" y="631.3988">spotchase</tspan></text>
 
        <g id="zzztimeAxis" transform="translate(0,40)"></g>
 
        <g id="mouse"></g>
 
        <g id="notes"></g>
 
      </g>
 
    </svg>
 
  </template>
 
</dom-module>
 

	
 
<dom-module id="light9-cursor-canvas">
 
  <template>
 
    <style>
light9/web/timeline/timeline.coffee
Show inline comments
 
@@ -289,12 +289,13 @@ coffeeElementSetup(class TimeZoomed exte
 
  @getter_properties:
 
    graph: { type: Object, notify: true }
 
    project: { type: Object }
 
    selection: { type: Object, notify: true }
 
    song: { type: String, notify: true }
 
    viewState: { type: Object, notify: true }
 
    inlineAttrConfigs: { type: Array, value: [] } # only for inlineattrs that should be displayed
 
  @getter_observers: [
 
    '_onGraph(graph, setAdjuster, song, viewState, project)',
 
  ]
 
  constructor: ->
 
    super()
 
    @notes = []
 
@@ -349,13 +350,13 @@ coffeeElementSetup(class TimeZoomed exte
 
      con = new PIXI.Container()
 
      con.interactive=true
 
      @stage.addChild(con)
 
      
 
      row = noteNum % 6
 
      rowTop = @viewState.rowsY() + 20 + 150 * row
 
      note = new Note(con, @project, @graph, @selection, uri, @setAdjuster, U(@song), @viewState, rowTop, rowTop + 140)
 
      note = new Note(@, con, @project, @graph, @selection, uri, @setAdjuster, U(@song), @viewState, rowTop, rowTop + 140)
 
      @notes.push(note)
 
      noteNum = noteNum + 1
 
 
 
    @renderer.render(@stage)
 
    
 
  onDrop: (effect, pos) ->
 
@@ -376,12 +377,29 @@ coffeeElementSetup(class TimeZoomed exte
 
    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)
 

	
 
  updateInlineAttrs: (note, config) ->
 
    if not config?
 
      index = 0
 
      for c in @inlineAttrConfigs
 
        if c.uri.equals(note)
 
          @splice('inlineAttrConfigs', index)
 
          return
 
        index += 1
 
    else
 
      index = 0
 
      for c in @inlineAttrConfigs
 
        if c.uri.equals(note)
 
          @splice('inlineAttrConfigs', index, 1, config)
 
          return
 
        index += 1
 
      @push('inlineAttrConfigs', config)
 
)
 

	
 

	
 
coffeeElementSetup(class TimeAxis extends Polymer.Element
 
  @is: "light9-timeline-time-axis",
 
  @getter_properties:
 
@@ -392,16 +410,16 @@ coffeeElementSetup(class TimeAxis extend
 
      pxPerTick = 50
 
      axis = d3.axisTop(@viewState.zoomInX).ticks(@viewState.width() / pxPerTick)
 
      d3.select(@$.axis).call(axis)
 
)
 

	
 

	
 
# Maintains a pixi object and some adjusters corresponding to a note
 
# Maintains a pixi object, some adjusters, and inlineattrs corresponding to a note
 
# in the graph.
 
class Note
 
  constructor: (@container, @project, @graph, @selection, @uri, @setAdjuster, @song, @viewState, @rowTopY, @rowBotY) ->
 
  constructor: (@parentElem, @container, @project, @graph, @selection, @uri, @setAdjuster, @song, @viewState, @rowTopY, @rowBotY) ->
 
    @adjusterIds = {} # id : true
 
    @graph.runHandler(@draw.bind(@), 'note draw')
 

	
 
  destroy: ->
 
    log('destroy', @uri.value)
 
    @isDetached = true
 
@@ -436,26 +454,32 @@ class Note
 

	
 
    shape = new PIXI.Polygon(screenPts)
 
    graphics.beginFill(@_noteColor(effect), .313)
 
    graphics.drawShape(shape)
 
    graphics.endFill()
 

	
 
    # stroke should vary with @selection.hover() == @uri and with @uri in @selection.selected()
 
    # 
 
    # #notes > path.hover {stroke-width: 1.5; stroke: #888;}
 
    # #notes > path.selected {stroke-width: 5; stroke: red;}
 
    graphics.lineStyle(2, 0xffd900, 1)
 
    graphics.moveTo(screenPts[0].x, screenPts[0].y)
 
    for p in screenPts.slice(1)
 
      graphics.lineTo(p.x, p.y)
 

	
 
    graphics.on 'mousedown', =>
 
    graphics.on 'mousedown', (ev) =>
 
      log('down gfx', @uri.value)
 
      @_onMouseDown(ev)
 

	
 
    graphics.on 'mouseover', =>
 
      log('hover', @uri.value)
 
      @selection.hover(@uri)
 

	
 
    graphics.on 'mouseout', =>
 
      log('hoverout', @uri.value)
 
      
 
      @selection.hover(null)
 

	
 
    @graphics = graphics
 
    curveWidthCalc = () => @project.curveWidth(worldPts)
 
    @_updateAdjusters(screenPts, worldPts, curveWidthCalc, yForV, @song)
 
    @_updateInlineAttrs(screenPts)
 
    
 
@@ -492,29 +516,32 @@ class Note
 
    else
 
      @_makeOffsetAdjuster(yForV, curveWidthCalc, ctx)
 
      @_makeCurvePointAdjusters(yForV, worldPts, ctx)
 
      @_makeFadeAdjusters(yForV, ctx, worldPts)
 

	
 
  _updateInlineAttrs: (screenPts) ->
 
    w = 280
 
    
 
    leftX = Math.max(2, screenPts[Math.min(1, screenPts.length - 1)].x + 5)
 
    rightX = screenPts[Math.min(2, screenPts.length - 1)].x - 5
 
    if screenPts.length < 3
 
      rightX = leftX + 120
 
    w = 250
 
    h = 110
 
    wasHidden = @inlineRect?.display == 'none'
 
    @inlineRect = {
 
      rightX = leftX + w
 

	
 
    if rightX - leftX < w or rightX < w or leftX > @parentElem.offsetWidth
 
      @parentElem.updateInlineAttrs(@uri, null)
 
      return
 

	
 
    config = {
 
      uri: @uri,
 
      left: leftX,
 
      top: @offsetTop + @offsetHeight - h - 5,
 
      top: @rowTopY + 5,
 
      width: w,
 
      height: h,
 
      display: if rightX - leftX > w then 'block' else 'none'
 
      height: @rowBotY - @rowTopY - 15,
 
      }
 
    if wasHidden and @inlineRect.display != 'none'
 
      @async =>
 
        @querySelector('light9-timeline-note-inline-attrs')?.displayed()
 

	
 
    @parentElem.updateInlineAttrs(@uri, config)
 
    
 
  _makeCurvePointAdjusters: (yForV, worldPts, ctx) ->
 
    for pointNum in [0...worldPts.length]
 
      @_makePointAdjuster(yForV, worldPts, pointNum, ctx)
 

	
 
  _makePointAdjuster: (yForV, worldPts, pointNum, ctx) ->
 
@@ -577,29 +604,22 @@ class Note
 
  _suggestedOffset: (pt) ->
 
    if pt.e(2) > .5
 
      $V([0, 30])
 
    else
 
      $V([0, -30])
 
    
 
  
 
  
 
  _addNoteListeners: (elem, uri) ->
 
    elem.addEventListener 'mouseenter', =>
 
      @selection.hover(uri)
 
    elem.addEventListener 'mousedown', (ev) =>
 
  _onMouseDown: (ev) ->
 
      sel = @selection.selected()
 
      if ev.getModifierState('Control')
 
        if uri in sel
 
          sel = _.without(sel, uri)
 
    if ev.data.originalEvent.ctrlKey
 
      if @uri in sel
 
        sel = _.without(sel, @uri)
 
        else
 
          sel.push(uri)
 
        sel.push(@uri)
 
      else
 
        sel = [uri]
 
      sel = [@uri]
 
      @selection.selected(sel)
 
    elem.addEventListener 'mouseleave', =>
 
      @selection.hover(null)
 

	
 
  _noteColor: (effect) ->
 
    effect = effect.value
 
    if effect in ['http://light9.bigasterisk.com/effect/blacklight',
 
      'http://light9.bigasterisk.com/effect/strobewarm']
 
      hue = 0
 
@@ -610,19 +630,10 @@ class Note
 
        hash += effect.charCodeAt(i)
 
      hue = (hash * 8) % 360
 
      sat = 40 + (hash % 20) # don't conceal colorscale too much
 

	
 
    return parseInt(tinycolor.fromRatio({h: hue / 360, s: sat / 100, l: .58}).toHex(), 16)
 

	
 
  _noteInDiagram: (uri) ->
 
    return !!@elemById[uri.value + '/area']
 

	
 
  _updateNotePathClasses: (uri, elem) ->
 
    ko.computed =>
 
      return if not @_noteInDiagram(uri)
 
      classes = 'light9-timeline-diagram-layer ' + (if @selection.hover() == uri then 'hover' else '') + ' '  + (if uri in @selection.selected() then 'selected' else '')
 
      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;
0 comments (0 inline, 0 general)