changeset 1743:92104dcd33e2

finish mouse event routing. inlineAttrs display again. Ignore-this: 5e5438f724a868ac12905a77e054d55
author Drew Perttula <drewp@bigasterisk.com>
date Sat, 19 May 2018 23:13:55 +0000
parents 70873145cc71
children ee3273dc1589
files light9/web/timeline/inline-attrs.coffee light9/web/timeline/inline-attrs.html light9/web/timeline/timeline-elements.html light9/web/timeline/timeline.coffee
diffstat 4 files changed, 77 insertions(+), 102 deletions(-) [+]
line wrap: on
line diff
--- a/light9/web/timeline/inline-attrs.coffee	Sat May 19 21:55:08 2018 +0000
+++ b/light9/web/timeline/inline-attrs.coffee	Sat May 19 23:13:55 2018 +0000
@@ -5,19 +5,27 @@
   @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
@@ -48,6 +56,7 @@
       @graph.applyAndSendPatch(patch)
     
   addHandler: ->
+    return
     @graph.runHandler(@update.bind(@), "update inline attrs #{@uri}")
     
   update: ->
--- a/light9/web/timeline/inline-attrs.html	Sat May 19 21:55:08 2018 +0000
+++ b/light9/web/timeline/inline-attrs.html	Sat May 19 23:13:55 2018 +0000
@@ -6,17 +6,20 @@
 <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>
@@ -24,7 +27,7 @@
           <light9-color-picker color="{{colorScale}}"></light9-color-picker>
         </td></tr>
       </table>
-    </div>
+
   </template>
   <script src="inline-attrs.js"></script>
 </dom-module>
--- a/light9/web/timeline/timeline-elements.html	Sat May 19 21:55:08 2018 +0000
+++ b/light9/web/timeline/timeline-elements.html	Sat May 19 23:13:55 2018 +0000
@@ -119,60 +119,12 @@
       </light9-timeline-audio>
     </div>
     <div id="rows"></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 {
-         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 is="dom-repeat" items="{{inlineAttrConfigs}}">
+      <light9-timeline-note-inline-attrs graph="{{graph}}"
+                                         song="{{song}}"
+                                         config="{{item}}"
+      ></light9-timeline-note-inline-attrs>
+    </template>
   </template>
 </dom-module>
 
--- a/light9/web/timeline/timeline.coffee	Sat May 19 21:55:08 2018 +0000
+++ b/light9/web/timeline/timeline.coffee	Sat May 19 23:13:55 2018 +0000
@@ -292,6 +292,7 @@
     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)',
   ]
@@ -302,7 +303,7 @@
     @stage.interactive=true
     
     @renderer = PIXI.autoDetectRenderer({
-         backgroundColor: 0x606060,
+        backgroundColor: 0x606060,
         antialias: true,
         forceCanvas: true,
     })
@@ -352,7 +353,7 @@
       
       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
  
@@ -379,6 +380,23 @@
     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)
 )
 
 
@@ -395,10 +413,10 @@
 )
 
 
-# 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')
 
@@ -439,20 +457,26 @@
     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)
@@ -495,23 +519,26 @@
       @_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]
@@ -579,24 +606,17 @@
       $V([0, 30])
     else
       $V([0, -30])
-    
   
-  
-  _addNoteListeners: (elem, uri) ->
-    elem.addEventListener 'mouseenter', =>
-      @selection.hover(uri)
-    elem.addEventListener 'mousedown', (ev) =>
-      sel = @selection.selected()
-      if ev.getModifierState('Control')
-        if uri in sel
-          sel = _.without(sel, uri)
-        else
-          sel.push(uri)
+  _onMouseDown: (ev) ->
+    sel = @selection.selected()
+    if ev.data.originalEvent.ctrlKey
+      if @uri in sel
+        sel = _.without(sel, @uri)
       else
-        sel = [uri]
-      @selection.selected(sel)
-    elem.addEventListener 'mouseleave', =>
-      @selection.hover(null)
+        sel.push(@uri)
+    else
+      sel = [@uri]
+    @selection.selected(sel)
 
   _noteColor: (effect) ->
     effect = effect.value
@@ -613,15 +633,6 @@
 
     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)