@checksub_team/peaks_timeline 1.4.27 → 1.4.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@checksub_team/peaks_timeline",
3
- "version": "1.4.27",
3
+ "version": "1.4.28",
4
4
  "description": "JavaScript UI component for displaying audio waveforms",
5
5
  "main": "./peaks.js",
6
6
  "types": "./peaks.js.d.ts",
package/peaks.js CHANGED
@@ -15146,7 +15146,7 @@ module.exports = function (Konva, Utils) {
15146
15146
  return Line;
15147
15147
  }(_dereq_('konva'), _dereq_('./utils'));
15148
15148
  },{"./utils":110,"konva":43}],92:[function(_dereq_,module,exports){
15149
- module.exports = function (Line, LineIndicator, Utils) {
15149
+ module.exports = function (SegmentsGroup, Line, LineIndicator, Utils) {
15150
15150
  'use strict';
15151
15151
  function Lines(peaks, view, layer) {
15152
15152
  this._peaks = peaks;
@@ -15157,12 +15157,42 @@ module.exports = function (Line, LineIndicator, Utils) {
15157
15157
  this._autoAddToLayer = false;
15158
15158
  this._areSourceInteractionsAllowed = true;
15159
15159
  this._areSegmentInteractionsAllowed = true;
15160
+ this._segmentsGroups = {};
15160
15161
  this._lineId = 0;
15161
15162
  this._lineIndicator = new LineIndicator(peaks, view, document.getElementById('line-indicator-container'));
15162
15163
  this._peaks.on('line.heightChanged', this._onLineHeightChanged.bind(this));
15163
15164
  this._peaks.on('line.add', this._onLineAdd.bind(this));
15164
15165
  this._peaks.on('line.remove', this._onLineRemove.bind(this));
15166
+ this._peaks.on('segment.updated', this._onSegmentsUpdate.bind(this));
15167
+ this._peaks.on('segments.add', this._onSegmentsAdd.bind(this));
15168
+ this._peaks.on('segments.remove', this._onSegmentsRemove.bind(this));
15169
+ this._peaks.on('segments.remove_all', this._onSegmentsRemoveAll.bind(this));
15170
+ this._peaks.on('segments.dragend', this._onSegmentUpdated.bind(this));
15165
15171
  }
15172
+ Lines.prototype._onSegmentsAdd = function (segments) {
15173
+ var self = this;
15174
+ segments.forEach(function (segment) {
15175
+ if (!self._segmentsGroups[segment.line]) {
15176
+ self._segmentsGroups[segment.line] = new SegmentsGroup(self._peaks, self._view, true);
15177
+ }
15178
+ self._segmentsGroups[segment.line].onSegmentsAdd([segment]);
15179
+ });
15180
+ };
15181
+ Lines.prototype._onSegmentsUpdate = function (segment) {
15182
+ this._segmentsGroups[segment.line].onSegmentsUpdate(segment);
15183
+ };
15184
+ Lines.prototype._onSegmentUpdated = function (segment) {
15185
+ this._segmentsGroups[segment.line].onSegmentUpdated();
15186
+ };
15187
+ Lines.prototype._onSegmentsRemove = function (segments) {
15188
+ var self = this;
15189
+ segments.forEach(function (segment) {
15190
+ self._segmentsGroups[segment.line].onSegmentsRemove([segment]);
15191
+ });
15192
+ };
15193
+ Lines.prototype._onSegmentsRemoveAll = function (lineId) {
15194
+ this._segmentsGroups[lineId].onSegmentsRemoveAll();
15195
+ };
15166
15196
  Lines.prototype._onLineHeightChanged = function (position) {
15167
15197
  this._updateLinesPosition(position);
15168
15198
  this._view.updateTimeline();
@@ -15195,11 +15225,10 @@ module.exports = function (Line, LineIndicator, Utils) {
15195
15225
  this._linesByPosition[position].addSourceGroup(sourceGroup);
15196
15226
  this._linesBySourceId[sourceGroup.getSource().id] = this._linesByPosition[position];
15197
15227
  };
15198
- Lines.prototype.addSegments = function (segmentsGroup, position) {
15228
+ Lines.prototype.addSegments = function (lineId, position) {
15199
15229
  this._createLine(position);
15200
15230
  this._linesByPosition[position].allowInteractions(this._areSegmentInteractionsAllowed);
15201
- this._linesByPosition[position].addSegments(segmentsGroup);
15202
- this._segmentsLine = this._linesByPosition[position];
15231
+ this._linesByPosition[position].addSegments(this._segmentsGroups[lineId]);
15203
15232
  this._setInteractions(position);
15204
15233
  this._updateLinesPosition(position);
15205
15234
  };
@@ -15232,6 +15261,9 @@ module.exports = function (Line, LineIndicator, Utils) {
15232
15261
  }
15233
15262
  return positions;
15234
15263
  };
15264
+ Lines.prototype.getSegmentsGroups = function () {
15265
+ return this._segmentsGroups;
15266
+ };
15235
15267
  Lines.prototype.addToLayer = function (layer) {
15236
15268
  for (var position in this._linesByPosition) {
15237
15269
  if (Utils.objectHasProperty(this._linesByPosition, position)) {
@@ -15364,8 +15396,10 @@ module.exports = function (Line, LineIndicator, Utils) {
15364
15396
  this._linesByPosition = newLinesByPosition;
15365
15397
  };
15366
15398
  Lines.prototype.updateSegments = function (frameStartTime, frameEndTime) {
15367
- if (this._segmentsLine) {
15368
- this._segmentsLine.updateSegments(frameStartTime, frameEndTime);
15399
+ for (var lineId in this._segmentsGroups) {
15400
+ if (Utils.objectHasProperty(this._segmentsGroups, lineId)) {
15401
+ this._segmentsGroups[lineId].updateSegments(frameStartTime, frameEndTime);
15402
+ }
15369
15403
  }
15370
15404
  };
15371
15405
  Lines.prototype.manageCollision = function (source, newStartX, newEndX) {
@@ -15401,8 +15435,8 @@ module.exports = function (Line, LineIndicator, Utils) {
15401
15435
  }
15402
15436
  };
15403
15437
  return Lines;
15404
- }(_dereq_('./line'), _dereq_('./line-indicator'), _dereq_('./utils'));
15405
- },{"./line":91,"./line-indicator":90,"./utils":110}],93:[function(_dereq_,module,exports){
15438
+ }(_dereq_('./segments-group'), _dereq_('./line'), _dereq_('./line-indicator'), _dereq_('./utils'));
15439
+ },{"./line":91,"./line-indicator":90,"./segments-group":102,"./utils":110}],93:[function(_dereq_,module,exports){
15406
15440
  module.exports = function (Colors, EventEmitter, TimelineSegments, TimelineSources, KeyboardHandler, Player, MarkerFactories, TimelineZoomView, Utils) {
15407
15441
  'use strict';
15408
15442
  function Peaks() {
@@ -15579,8 +15613,11 @@ module.exports = function (Colors, EventEmitter, TimelineSegments, TimelineSourc
15579
15613
  Peaks.prototype.hideSource = function (sourceId) {
15580
15614
  this.sources.hideById(sourceId);
15581
15615
  };
15582
- Peaks.prototype.showSegments = function (position) {
15583
- this.segments.addSegmentsToPosition(position);
15616
+ Peaks.prototype.showSegments = function (lineId, position) {
15617
+ this.segments.addSegmentsToPosition(lineId, position);
15618
+ };
15619
+ Peaks.prototype.destroySegment = function (segmentId) {
15620
+ this.segments.removeById(segmentId);
15584
15621
  };
15585
15622
  Peaks.prototype.setDefaultMode = function () {
15586
15623
  this.emit('default_mode');
@@ -15604,7 +15641,7 @@ module.exports = function (Colors, EventEmitter, TimelineSegments, TimelineSourc
15604
15641
  return this.view.selectSourceById(sourceId);
15605
15642
  };
15606
15643
  Peaks.prototype.deselectSource = function () {
15607
- return this.view.deselectSource();
15644
+ return this.view.deselectElement();
15608
15645
  };
15609
15646
  Peaks.prototype._addWindowResizeHandler = function () {
15610
15647
  this._onResize = this._onResize.bind(this);
@@ -15693,21 +15730,29 @@ module.exports = function (Utils, SourceGroup, Konva) {
15693
15730
  ModeLayer.prototype.addToStage = function (stage) {
15694
15731
  stage.add(this._layer);
15695
15732
  };
15696
- ModeLayer.prototype.selectSourceGroup = function (sourceGroup, notify) {
15697
- this.deselectSourceGroup();
15698
- if (sourceGroup) {
15699
- this._selectedElement = sourceGroup;
15733
+ ModeLayer.prototype.selectElement = function (element, notify) {
15734
+ this.deselectElement(notify);
15735
+ if (element) {
15736
+ this._selectedElement = element;
15700
15737
  this._selectedElement.setSelected(true);
15701
15738
  if (notify) {
15702
- this._peaks.emit('source.selected', this._selectedElement.getSource());
15739
+ if (element instanceof SourceGroup) {
15740
+ this._peaks.emit('source.selected', this._selectedElement.getSource());
15741
+ } else {
15742
+ this._peaks.emit('segment.selected', this._selectedElement.getSegment());
15743
+ }
15703
15744
  }
15704
15745
  }
15705
15746
  };
15706
- ModeLayer.prototype.deselectSourceGroup = function (notify) {
15747
+ ModeLayer.prototype.deselectElement = function (notify) {
15707
15748
  if (this._selectedElement) {
15708
15749
  this._selectedElement.setSelected(false);
15709
15750
  if (notify) {
15710
- this._peaks.emit('source.deselected', this._selectedElement.getSource());
15751
+ if (this._selectedElement instanceof SourceGroup) {
15752
+ this._peaks.emit('source.deselected', this._selectedElement.getSource());
15753
+ } else {
15754
+ this._peaks.emit('segment.deselected', this._selectedElement.getSegment());
15755
+ }
15711
15756
  }
15712
15757
  this._selectedElement = null;
15713
15758
  }
@@ -15763,14 +15808,22 @@ module.exports = function (Utils, SourceGroup, Konva) {
15763
15808
  ModeLayer.prototype._onMouseClickInDefaultMode = function () {
15764
15809
  var hoveredElement = this._view.getHoveredElement();
15765
15810
  if (hoveredElement) {
15766
- this.selectSourceGroup(hoveredElement, true);
15811
+ this.selectElement(hoveredElement, true);
15767
15812
  } else {
15768
- this.deselectSourceGroup(true);
15813
+ this.deselectElement(true);
15769
15814
  }
15770
15815
  };
15771
15816
  ModeLayer.prototype._onKeyboardDelete = function () {
15772
15817
  if (this._selectedElement) {
15773
- this._peaks.destroySource(this._selectedElement.getSource().id);
15818
+ var selectedElement = this._selectedElement;
15819
+ this.deselectElement(true);
15820
+ if (selectedElement instanceof SourceGroup) {
15821
+ this._peaks.destroySource(selectedElement.getSource().id);
15822
+ } else {
15823
+ if (selectedElement.getSegment().allowDeletion) {
15824
+ this._peaks.destroySegment(selectedElement.getSegment().id);
15825
+ }
15826
+ }
15774
15827
  }
15775
15828
  };
15776
15829
  ModeLayer.prototype._onMouseEnterInCutMode = function () {
@@ -15888,7 +15941,7 @@ module.exports = function (Utils, SourceGroup, Konva) {
15888
15941
  this._peaks.off('keyboard.delete', this._onKeyboardDelete);
15889
15942
  break;
15890
15943
  }
15891
- this.deselectSourceGroup(true);
15944
+ this.deselectElement(true);
15892
15945
  switch (mode) {
15893
15946
  case 'cut':
15894
15947
  this._stage.on('mouseover', this._onMouseEnterInCutMode);
@@ -16110,18 +16163,18 @@ module.exports = function (Utils) {
16110
16163
  module.exports = function (Utils, Konva) {
16111
16164
  'use strict';
16112
16165
  var HANDLE_RADIUS = 10;
16113
- function PlayheadLayer(peaks, view, segmentsGroup, showTime) {
16166
+ function PlayheadLayer(peaks, view, lines, showTime) {
16114
16167
  this._peaks = peaks;
16115
16168
  this._view = view;
16116
- this._segmentsGroup = segmentsGroup;
16169
+ this._lines = lines;
16117
16170
  this._playheadPixel = 0;
16118
16171
  this._playheadLineAnimation = null;
16119
16172
  this._playheadVisible = false;
16120
16173
  this._playheadColor = peaks.options.playheadColor;
16121
16174
  this._playheadTextColor = peaks.options.playheadTextColor;
16122
16175
  this._playheadLayer = new Konva.Layer();
16123
- this._activeSegment = null;
16124
- this._lastActiveSegmentId = null;
16176
+ this._activeSegments = {};
16177
+ this._lastActiveSegments = {};
16125
16178
  this._createPlayhead(this._playheadColor);
16126
16179
  if (showTime) {
16127
16180
  this._createPlayheadText(this._playheadTextColor);
@@ -16132,20 +16185,20 @@ module.exports = function (Utils, Konva) {
16132
16185
  this._peaks.on('segments.remove', this._onSegmentsRemove.bind(this));
16133
16186
  }
16134
16187
  PlayheadLayer.prototype._onSegmentsRemoveAll = function () {
16135
- this._activeSegment = null;
16136
- this._lastActiveSegmentId = null;
16188
+ this._activeSegments = {};
16189
+ this._lastActiveSegments = {};
16137
16190
  };
16138
16191
  PlayheadLayer.prototype._onSegmentsRemove = function (segments) {
16139
- if (this._activeSegment || this._lastActiveSegmentId) {
16140
- var activeSegmentId = this._activeSegment ? this._activeSegment.id : null;
16141
- var lastActiveSegmentId = this._lastActiveSegmentId ? this._lastActiveSegmentId.id : null;
16192
+ if (this._activeSegments || this._lastActiveSegments) {
16142
16193
  for (var id in segments) {
16143
16194
  if (Utils.objectHasProperty(segments, id)) {
16195
+ var activeSegmentId = this._activeSegments[segments[id].line] ? this._activeSegments[segments[id].line].id : null;
16196
+ var lastActiveSegmentId = this._lastActiveSegments[segments[id].line] ? this._lastActiveSegments[segments[id].line].id : null;
16144
16197
  if (segments[id].id === activeSegmentId) {
16145
- this._activeSegment = null;
16198
+ delete this._activeSegments[segments[id].line];
16146
16199
  }
16147
16200
  if (segments[id].id === lastActiveSegmentId) {
16148
- this._lastActiveSegmentId = null;
16201
+ delete this._lastActiveSegments[segments[id].line];
16149
16202
  }
16150
16203
  }
16151
16204
  }
@@ -16263,16 +16316,21 @@ module.exports = function (Utils, Konva) {
16263
16316
  }
16264
16317
  var playheadPositionDiff = this._playheadGroup.x() - playheadX;
16265
16318
  if (playheadPositionDiff) {
16266
- var newActiveSegment = this._segmentsGroup.getActiveSegment(this._view.pixelsToTime(playheadX + frameOffset), null, true);
16267
- if (newActiveSegment !== this._activeSegment) {
16268
- if (this._activeSegment) {
16269
- this._peaks.emit('segments.exit', this._activeSegment);
16270
- this._activeSegment = null;
16271
- }
16272
- if (newActiveSegment) {
16273
- this._peaks.emit('segments.enter', newActiveSegment);
16274
- this._activeSegment = newActiveSegment;
16275
- this._lastActiveSegment = this._activeSegment;
16319
+ var segmentsGroup = this._lines.getSegmentsGroups();
16320
+ for (var lineId in segmentsGroup) {
16321
+ if (Utils.objectHasProperty(segmentsGroup, lineId)) {
16322
+ var newActiveSegment = segmentsGroup[lineId].getActiveSegment(this._view.pixelsToTime(playheadX + frameOffset), null, true);
16323
+ if (newActiveSegment !== this._activeSegments[lineId]) {
16324
+ if (this._activeSegments[lineId]) {
16325
+ this._peaks.emit('segments.exit', this._activeSegments[lineId]);
16326
+ delete this._activeSegments[lineId];
16327
+ }
16328
+ if (newActiveSegment) {
16329
+ this._peaks.emit('segments.enter', newActiveSegment);
16330
+ this._activeSegments[lineId] = newActiveSegment;
16331
+ this._lastActiveSegments[lineId] = this._activeSegments[lineId];
16332
+ }
16333
+ }
16276
16334
  }
16277
16335
  }
16278
16336
  }
@@ -16446,6 +16504,7 @@ module.exports = function (Konva, SegmentMarker) {
16446
16504
  this._startMarker = null;
16447
16505
  this._endMarker = null;
16448
16506
  this._rectangle = null;
16507
+ this._isSelected = false;
16449
16508
  this._segmentHeight = this._peaks.options.segmentHeight;
16450
16509
  this._rectangle = new Konva.Rect({
16451
16510
  x: this._view.timeToPixels(this._segment.startTime),
@@ -16604,12 +16663,14 @@ module.exports = function (Konva, SegmentMarker) {
16604
16663
  };
16605
16664
  SegmentShape.prototype._onMouseEnter = function () {
16606
16665
  this._view.setCursor('pointer');
16607
- this._rectangle.fill(this._segment.selectedColor + Math.round(this._segment.opacity * 255).toString(16));
16666
+ this._view.setHoveredElement(this);
16667
+ this._rectangle.fill(this._segment.activeColor + Math.round(this._segment.opacity * 255).toString(16));
16608
16668
  this._view.drawSourcesLayer();
16609
16669
  this._peaks.emit('segments.mouseenter', this._segment);
16610
16670
  };
16611
16671
  SegmentShape.prototype._onMouseLeave = function () {
16612
16672
  this._view.setCursor('default');
16673
+ this._view.setHoveredElement(null);
16613
16674
  this._rectangle.fill(this._segment.color + Math.round(this._segment.opacity * 255).toString(16));
16614
16675
  this._view.drawSourcesLayer();
16615
16676
  this._peaks.emit('segments.mouseleave', this._segment);
@@ -16641,6 +16702,9 @@ module.exports = function (Konva, SegmentMarker) {
16641
16702
  var startMarker = segmentMarker.isStartMarker();
16642
16703
  this._peaks.emit('segments.dragend', this._segment, startMarker);
16643
16704
  };
16705
+ SegmentShape.prototype.setSelected = function (isSelected) {
16706
+ this._isSelected = isSelected;
16707
+ };
16644
16708
  SegmentShape.prototype.fitToView = function () {
16645
16709
  if (this._startMarker) {
16646
16710
  this._startMarker.fitToView();
@@ -16693,8 +16757,11 @@ module.exports = function (Utils) {
16693
16757
  } else if (!Utils.isString(options.labelText)) {
16694
16758
  throw new TypeError('peaks.segments.' + context + ': labelText must be a string');
16695
16759
  }
16760
+ if (!Utils.isInteger(options.line)) {
16761
+ throw new TypeError('peaks.segments.' + context + ': line must be an integer');
16762
+ }
16696
16763
  }
16697
- function Segment(peaks, id, startTime, endTime, labelText, color, textColor, handleTextColor, opacity, editable) {
16764
+ function Segment(peaks, id, startTime, endTime, labelText, color, textColor, handleTextColor, opacity, editable, allowDeletion, line) {
16698
16765
  var opts = {
16699
16766
  startTime: startTime,
16700
16767
  endTime: endTime,
@@ -16703,7 +16770,9 @@ module.exports = function (Utils) {
16703
16770
  textColor: textColor,
16704
16771
  handleTextColor: handleTextColor,
16705
16772
  opacity: opacity,
16706
- editable: editable
16773
+ editable: editable,
16774
+ allowDeletion: allowDeletion,
16775
+ line: line
16707
16776
  };
16708
16777
  validateSegment(peaks, opts, 'add()');
16709
16778
  this._peaks = peaks;
@@ -16712,11 +16781,13 @@ module.exports = function (Utils) {
16712
16781
  this._endTime = opts.endTime;
16713
16782
  this._labelText = opts.labelText;
16714
16783
  this._color = opts.color;
16715
- this._selectedColor = Utils.shadeColor(color, 20);
16784
+ this._activeColor = Utils.shadeColor(color, 20);
16716
16785
  this._textColor = opts.textColor;
16717
16786
  this._handleTextColor = opts.handleTextColor;
16718
16787
  this._opacity = opts.opacity;
16719
16788
  this._editable = opts.editable;
16789
+ this._allowDeletion = opts.allowDeletion;
16790
+ this._line = opts.line;
16720
16791
  this._minSize = peaks.options.minSegmentSize;
16721
16792
  }
16722
16793
  Object.defineProperties(Segment.prototype, {
@@ -16756,10 +16827,10 @@ module.exports = function (Utils) {
16756
16827
  return this._color;
16757
16828
  }
16758
16829
  },
16759
- selectedColor: {
16830
+ activeColor: {
16760
16831
  enumerable: true,
16761
16832
  get: function () {
16762
- return this._selectedColor;
16833
+ return this._activeColor;
16763
16834
  }
16764
16835
  },
16765
16836
  textColor: {
@@ -16786,6 +16857,18 @@ module.exports = function (Utils) {
16786
16857
  return this._editable;
16787
16858
  }
16788
16859
  },
16860
+ allowDeletion: {
16861
+ enumerable: true,
16862
+ get: function () {
16863
+ return this._allowDeletion;
16864
+ }
16865
+ },
16866
+ line: {
16867
+ enumerable: true,
16868
+ get: function () {
16869
+ return this._line;
16870
+ }
16871
+ },
16789
16872
  minSize: {
16790
16873
  enumerable: true,
16791
16874
  get: function () {
@@ -16802,7 +16885,9 @@ module.exports = function (Utils) {
16802
16885
  textColor: this.textColor,
16803
16886
  handleTextColor: this.handleTextColor,
16804
16887
  opacity: this.opacity,
16805
- editable: this.editable
16888
+ editable: this.editable,
16889
+ allowDeletion: this.allowDeletion,
16890
+ line: this.line
16806
16891
  };
16807
16892
  Utils.extend(opts, options);
16808
16893
  validateSegment(this._peaks, opts, 'update()');
@@ -16814,6 +16899,8 @@ module.exports = function (Utils) {
16814
16899
  this._handleTextColor = opts.handleTextColor;
16815
16900
  this._opacity = opts.opacity;
16816
16901
  this._editable = opts.editable;
16902
+ this._allowDeletion = opts.allowDeletion;
16903
+ this._line = opts.line;
16817
16904
  this._peaks.emit('segment.updated', this);
16818
16905
  };
16819
16906
  Segment.prototype.isVisible = function (startTime, endTime) {
@@ -16835,11 +16922,6 @@ module.exports = function (SegmentShape, Utils, Konva) {
16835
16922
  this._group = new Konva.Group();
16836
16923
  this._updatedSegments = [];
16837
16924
  this._isMagnetized = false;
16838
- this._peaks.on('segment.updated', this._onSegmentsUpdate.bind(this));
16839
- this._peaks.on('segments.add', this._onSegmentsAdd.bind(this));
16840
- this._peaks.on('segments.remove', this._onSegmentsRemove.bind(this));
16841
- this._peaks.on('segments.remove_all', this._onSegmentsRemoveAll.bind(this));
16842
- this._peaks.on('segments.dragend', this._onSegmentUpdated.bind(this));
16843
16925
  this._peaks.on('segments.setMagnetizing', this.setMagnetizing.bind(this));
16844
16926
  }
16845
16927
  SegmentsGroup.prototype.addToGroup = function (group) {
@@ -16882,7 +16964,7 @@ module.exports = function (SegmentShape, Utils, Konva) {
16882
16964
  } while (nextSegmentId);
16883
16965
  return activeSegment;
16884
16966
  };
16885
- SegmentsGroup.prototype._onSegmentsUpdate = function (segment) {
16967
+ SegmentsGroup.prototype.onSegmentsUpdate = function (segment) {
16886
16968
  if (this._segments[segment.id]) {
16887
16969
  var redraw = false;
16888
16970
  var segmentShape = this._segmentShapes[segment.id];
@@ -16905,11 +16987,11 @@ module.exports = function (SegmentShape, Utils, Konva) {
16905
16987
  }
16906
16988
  }
16907
16989
  };
16908
- SegmentsGroup.prototype._onSegmentUpdated = function () {
16990
+ SegmentsGroup.prototype.onSegmentUpdated = function () {
16909
16991
  this._peaks.emit('segments.updated', this._updatedSegments);
16910
16992
  this._updatedSegments = [];
16911
16993
  };
16912
- SegmentsGroup.prototype._onSegmentsAdd = function (segments) {
16994
+ SegmentsGroup.prototype.onSegmentsAdd = function (segments) {
16913
16995
  var self = this;
16914
16996
  var frameOffset = self._view.getFrameOffset();
16915
16997
  var width = self._view.getWidth();
@@ -16920,7 +17002,7 @@ module.exports = function (SegmentShape, Utils, Konva) {
16920
17002
  });
16921
17003
  self.updateSegments(frameStartTime, frameEndTime);
16922
17004
  };
16923
- SegmentsGroup.prototype._onSegmentsRemove = function (segments) {
17005
+ SegmentsGroup.prototype.onSegmentsRemove = function (segments) {
16924
17006
  var self = this;
16925
17007
  segments.forEach(function (segment) {
16926
17008
  var index = self._updatedSegments.indexOf(segment);
@@ -16932,7 +17014,7 @@ module.exports = function (SegmentShape, Utils, Konva) {
16932
17014
  });
16933
17015
  this._draw();
16934
17016
  };
16935
- SegmentsGroup.prototype._onSegmentsRemoveAll = function () {
17017
+ SegmentsGroup.prototype.onSegmentsRemoveAll = function () {
16936
17018
  this._group.removeChildren();
16937
17019
  this._firstSegmentId = null;
16938
17020
  this._segments = {};
@@ -17013,7 +17095,7 @@ module.exports = function (SegmentShape, Utils, Konva) {
17013
17095
  this._updateSegments(segment, marker);
17014
17096
  };
17015
17097
  SegmentsGroup.prototype.updateSegments = function (startTime, endTime) {
17016
- var segments = this._peaks.segments.find(startTime, endTime);
17098
+ var segments = this.find(startTime, endTime);
17017
17099
  var count = segments.length;
17018
17100
  segments.forEach(this._updateSegment.bind(this));
17019
17101
  count += this._removeInvisibleSegments(startTime, endTime);
@@ -17021,6 +17103,23 @@ module.exports = function (SegmentShape, Utils, Konva) {
17021
17103
  this._draw();
17022
17104
  }
17023
17105
  };
17106
+ SegmentsGroup.prototype.find = function (startTime, endTime) {
17107
+ var currentSegment = null;
17108
+ var visibleSegments = [];
17109
+ do {
17110
+ if (!currentSegment) {
17111
+ currentSegment = this._segments[this._firstSegmentId];
17112
+ } else {
17113
+ currentSegment = this._segments[currentSegment.nextSegmentId];
17114
+ }
17115
+ if (currentSegment.segment.isVisible(startTime, endTime)) {
17116
+ visibleSegments.push(currentSegment.segment);
17117
+ } else if (visibleSegments.length) {
17118
+ break;
17119
+ }
17120
+ } while (currentSegment.nextSegmentId);
17121
+ return visibleSegments;
17122
+ };
17024
17123
  SegmentsGroup.prototype._draw = function () {
17025
17124
  this._view.drawSourcesLayer();
17026
17125
  };
@@ -17265,11 +17364,7 @@ module.exports = function (SegmentShape, Utils, Konva) {
17265
17364
  return endsLater || startsEarlier;
17266
17365
  };
17267
17366
  SegmentsGroup.prototype.destroy = function () {
17268
- this._peaks.off('segment.updated', this._onSegmentsUpdate);
17269
- this._peaks.off('segments.add', this._onSegmentsAdd);
17270
- this._peaks.off('segments.remove', this._onSegmentsRemove);
17271
- this._peaks.off('segments.remove_all', this._onSegmentsRemoveAll);
17272
- this._peaks.off('segments.dragged', this._onSegmentsDragged);
17367
+ this._peaks.off('segments.setMagnetizing', this.setMagnetizing);
17273
17368
  };
17274
17369
  SegmentsGroup.prototype.fitToView = function () {
17275
17370
  for (var segmentId in this._segmentShapes) {
@@ -18552,7 +18647,7 @@ module.exports = function (Utils) {
18552
18647
  return Source;
18553
18648
  }(_dereq_('./utils'));
18554
18649
  },{"./utils":110}],105:[function(_dereq_,module,exports){
18555
- module.exports = function (SourceGroup, SegmentsGroup, Lines, DataRetriever, Utils, Invoker, Konva) {
18650
+ module.exports = function (SourceGroup, Lines, DataRetriever, Utils, Invoker, Konva) {
18556
18651
  'use strict';
18557
18652
  function SourcesLayer(peaks, view, allowEditing) {
18558
18653
  this._peaks = peaks;
@@ -18563,7 +18658,6 @@ module.exports = function (SourceGroup, SegmentsGroup, Lines, DataRetriever, Uti
18563
18658
  this._dataRetriever = new DataRetriever(peaks);
18564
18659
  this._lines = new Lines(peaks, view, this);
18565
18660
  this._lines.addToLayer(this);
18566
- this._segmentsGroup = new SegmentsGroup(peaks, view, true);
18567
18661
  this._loadedData = {};
18568
18662
  this._debouncedRescale = new Invoker().debounce(this._rescale, 150);
18569
18663
  this._peaks.on('sources.add', this._onSourcesAdd.bind(this));
@@ -18582,8 +18676,8 @@ module.exports = function (SourceGroup, SegmentsGroup, Lines, DataRetriever, Uti
18582
18676
  SourcesLayer.prototype.setLoadedData = function (id, data) {
18583
18677
  this._loadedData[id] = data;
18584
18678
  };
18585
- SourcesLayer.prototype.getSegmentsGroup = function () {
18586
- return this._segmentsGroup;
18679
+ SourcesLayer.prototype.getSegmentsGroups = function () {
18680
+ return this._lines.getSegmentsGroups();
18587
18681
  };
18588
18682
  SourcesLayer.prototype.add = function (element) {
18589
18683
  this._layer.add(element);
@@ -18703,8 +18797,8 @@ module.exports = function (SourceGroup, SegmentsGroup, Lines, DataRetriever, Uti
18703
18797
  SourcesLayer.prototype._onSourcesRefresh = function () {
18704
18798
  this._layer.draw();
18705
18799
  };
18706
- SourcesLayer.prototype._onSegmentsShow = function (position) {
18707
- this._lines.addSegments(this._segmentsGroup, position);
18800
+ SourcesLayer.prototype._onSegmentsShow = function (lineId, position) {
18801
+ this._lines.addSegments(lineId, position);
18708
18802
  this._view.updateTimelineLength();
18709
18803
  this._layer.draw();
18710
18804
  };
@@ -18898,8 +18992,8 @@ module.exports = function (SourceGroup, SegmentsGroup, Lines, DataRetriever, Uti
18898
18992
  return this._lines.linesLength();
18899
18993
  };
18900
18994
  return SourcesLayer;
18901
- }(_dereq_('./source-group'), _dereq_('./segments-group'), _dereq_('./lines'), _dereq_('./data-retriever'), _dereq_('./utils'), _dereq_('./invoker'), _dereq_('konva'));
18902
- },{"./data-retriever":85,"./invoker":88,"./lines":92,"./segments-group":102,"./source-group":103,"./utils":110,"konva":43}],106:[function(_dereq_,module,exports){
18995
+ }(_dereq_('./source-group'), _dereq_('./lines'), _dereq_('./data-retriever'), _dereq_('./utils'), _dereq_('./invoker'), _dereq_('konva'));
18996
+ },{"./data-retriever":85,"./invoker":88,"./lines":92,"./source-group":103,"./utils":110,"konva":43}],106:[function(_dereq_,module,exports){
18903
18997
  module.exports = function (Utils, Konva) {
18904
18998
  'use strict';
18905
18999
  var LEFT_PADDING = 4;
@@ -19083,14 +19177,14 @@ module.exports = function (Colors, Segment, Utils) {
19083
19177
  if (!Utils.isObject(options)) {
19084
19178
  throw new TypeError('peaks.segments.add(): expected a Segment object parameter');
19085
19179
  }
19086
- var segment = new Segment(this._peaks, Utils.isNullOrUndefined(options.id) ? this._getNextSegmentId() : options.id, options.startTime, options.endTime, options.labelText, options.color || this._getSegmentColor(), options.textColor || '#000000', options.handleTextColor || '#000000', options.opacity || 1, true);
19180
+ var segment = new Segment(this._peaks, Utils.isNullOrUndefined(options.id) ? this._getNextSegmentId() : options.id, options.startTime, options.endTime, options.labelText, options.color || this._getSegmentColor(), options.textColor || '#000000', options.handleTextColor || '#000000', options.opacity || 1, true, options.allowDeletion || false, options.line);
19087
19181
  return segment;
19088
19182
  };
19089
19183
  TimelineSegments.prototype.getSegments = function () {
19090
19184
  return this._segments;
19091
19185
  };
19092
- TimelineSegments.prototype.addSegmentsToPosition = function (position) {
19093
- this._peaks.emit('segments.show', position);
19186
+ TimelineSegments.prototype.addSegmentsToPosition = function (lineId, position) {
19187
+ this._peaks.emit('segments.show', lineId, position);
19094
19188
  };
19095
19189
  TimelineSegments.prototype.getSegment = function (id) {
19096
19190
  return this._segmentsById[id] || null;
@@ -19181,10 +19275,10 @@ module.exports = function (Colors, Segment, Utils) {
19181
19275
  }
19182
19276
  return this._removeSegments(fnFilter);
19183
19277
  };
19184
- TimelineSegments.prototype.removeAll = function () {
19278
+ TimelineSegments.prototype.removeAll = function (lineId) {
19185
19279
  this._segments = [];
19186
19280
  this._segmentsById = {};
19187
- this._peaks.emit('segments.remove_all');
19281
+ this._peaks.emit('segments.remove_all', lineId);
19188
19282
  };
19189
19283
  return TimelineSegments;
19190
19284
  }(_dereq_('colors.css'), _dereq_('./segment'), _dereq_('./utils'));
@@ -19428,7 +19522,7 @@ module.exports = function (MouseDragHandler, PlayheadLayer, SourcesLayer, ModeLa
19428
19522
  self._sourcesLayer = new SourcesLayer(peaks, self, true);
19429
19523
  self._sourcesLayer.addToStage(self._stage);
19430
19524
  self._axis.addFrontToStage(self._stage);
19431
- self._playheadLayer = new PlayheadLayer(peaks, self, self._sourcesLayer.getSegmentsGroup(), self._options.showPlayheadTime);
19525
+ self._playheadLayer = new PlayheadLayer(peaks, self, self._sourcesLayer, self._options.showPlayheadTime);
19432
19526
  self._playheadLayer.addToStage(self._stage);
19433
19527
  var time = self._peaks.player.getCurrentTime();
19434
19528
  self._syncPlayhead(time);
@@ -19576,11 +19670,11 @@ module.exports = function (MouseDragHandler, PlayheadLayer, SourcesLayer, ModeLa
19576
19670
  TimelineZoomView.prototype.selectSourceById = function (sourceId) {
19577
19671
  var sourceGroup = this._sourcesLayer.getSourceGroupById(sourceId);
19578
19672
  if (sourceGroup) {
19579
- this._modeLayer.selectSourceGroup(sourceGroup, false);
19673
+ this._modeLayer.selectElement(sourceGroup, false);
19580
19674
  }
19581
19675
  };
19582
- TimelineZoomView.prototype.deselectSource = function () {
19583
- this._modeLayer.deselectSourceGroup(false);
19676
+ TimelineZoomView.prototype.deselectElement = function () {
19677
+ this._modeLayer.deselectElement(false);
19584
19678
  };
19585
19679
  TimelineZoomView.prototype.isListening = function () {
19586
19680
  return this._stage.listening();
package/src/lines.js CHANGED
@@ -7,10 +7,12 @@
7
7
  */
8
8
 
9
9
  define([
10
+ './segments-group',
10
11
  './line',
11
12
  './line-indicator',
12
13
  './utils'
13
14
  ], function(
15
+ SegmentsGroup,
14
16
  Line,
15
17
  LineIndicator,
16
18
  Utils) {
@@ -26,6 +28,8 @@ define([
26
28
  this._areSourceInteractionsAllowed = true;
27
29
  this._areSegmentInteractionsAllowed = true;
28
30
 
31
+ this._segmentsGroups = {};
32
+
29
33
  this._lineId = 0;
30
34
 
31
35
  this._lineIndicator = new LineIndicator(
@@ -37,8 +41,46 @@ define([
37
41
  this._peaks.on('line.heightChanged', this._onLineHeightChanged.bind(this));
38
42
  this._peaks.on('line.add', this._onLineAdd.bind(this));
39
43
  this._peaks.on('line.remove', this._onLineRemove.bind(this));
44
+
45
+ this._peaks.on('segment.updated', this._onSegmentsUpdate.bind(this));
46
+ this._peaks.on('segments.add', this._onSegmentsAdd.bind(this));
47
+ this._peaks.on('segments.remove', this._onSegmentsRemove.bind(this));
48
+ this._peaks.on('segments.remove_all', this._onSegmentsRemoveAll.bind(this));
49
+ this._peaks.on('segments.dragend', this._onSegmentUpdated.bind(this));
40
50
  }
41
51
 
52
+ Lines.prototype._onSegmentsAdd = function(segments) {
53
+ var self = this;
54
+
55
+ segments.forEach(function(segment) {
56
+ if (!self._segmentsGroups[segment.line]) {
57
+ self._segmentsGroups[segment.line] = new SegmentsGroup(self._peaks, self._view, true);
58
+ }
59
+
60
+ self._segmentsGroups[segment.line].onSegmentsAdd([segment]);
61
+ });
62
+ };
63
+
64
+ Lines.prototype._onSegmentsUpdate = function(segment) {
65
+ this._segmentsGroups[segment.line].onSegmentsUpdate(segment);
66
+ };
67
+
68
+ Lines.prototype._onSegmentUpdated = function(segment) {
69
+ this._segmentsGroups[segment.line].onSegmentUpdated();
70
+ };
71
+
72
+ Lines.prototype._onSegmentsRemove = function(segments) {
73
+ var self = this;
74
+
75
+ segments.forEach(function(segment) {
76
+ self._segmentsGroups[segment.line].onSegmentsRemove([segment]);
77
+ });
78
+ };
79
+
80
+ Lines.prototype._onSegmentsRemoveAll = function(lineId) {
81
+ this._segmentsGroups[lineId].onSegmentsRemoveAll();
82
+ };
83
+
42
84
  Lines.prototype._onLineHeightChanged = function(position) {
43
85
  this._updateLinesPosition(position);
44
86
  this._view.updateTimeline();
@@ -78,12 +120,11 @@ define([
78
120
  this._linesBySourceId[sourceGroup.getSource().id] = this._linesByPosition[position];
79
121
  };
80
122
 
81
- Lines.prototype.addSegments = function(segmentsGroup, position) {
123
+ Lines.prototype.addSegments = function(lineId, position) {
82
124
  this._createLine(position);
83
125
 
84
126
  this._linesByPosition[position].allowInteractions(this._areSegmentInteractionsAllowed);
85
- this._linesByPosition[position].addSegments(segmentsGroup);
86
- this._segmentsLine = this._linesByPosition[position];
127
+ this._linesByPosition[position].addSegments(this._segmentsGroups[lineId]);
87
128
 
88
129
  this._setInteractions(position);
89
130
 
@@ -130,6 +171,10 @@ define([
130
171
  return positions;
131
172
  };
132
173
 
174
+ Lines.prototype.getSegmentsGroups = function() {
175
+ return this._segmentsGroups;
176
+ };
177
+
133
178
  Lines.prototype.addToLayer = function(layer) {
134
179
  for (var position in this._linesByPosition) {
135
180
  if (Utils.objectHasProperty(this._linesByPosition, position)) {
@@ -302,8 +347,10 @@ define([
302
347
  };
303
348
 
304
349
  Lines.prototype.updateSegments = function(frameStartTime, frameEndTime) {
305
- if (this._segmentsLine) {
306
- this._segmentsLine.updateSegments(frameStartTime, frameEndTime);
350
+ for (var lineId in this._segmentsGroups) {
351
+ if (Utils.objectHasProperty(this._segmentsGroups, lineId)) {
352
+ this._segmentsGroups[lineId].updateSegments(frameStartTime, frameEndTime);
353
+ }
307
354
  }
308
355
  };
309
356
 
package/src/main.js CHANGED
@@ -596,8 +596,18 @@ define([
596
596
  this.sources.hideById(sourceId);
597
597
  };
598
598
 
599
- Peaks.prototype.showSegments = function(position) {
600
- this.segments.addSegmentsToPosition(position);
599
+ Peaks.prototype.showSegments = function(lineId, position) {
600
+ this.segments.addSegmentsToPosition(lineId, position);
601
+ };
602
+
603
+ /**
604
+ * Destroy a segment from the {@link Peaks} instance.
605
+ *
606
+ * @param {String} segmentId
607
+ */
608
+
609
+ Peaks.prototype.destroySegment = function(segmentId) {
610
+ this.segments.removeById(segmentId);
601
611
  };
602
612
 
603
613
  Peaks.prototype.setDefaultMode = function() {
@@ -635,7 +645,7 @@ define([
635
645
 
636
646
  Peaks.prototype.deselectSource = function() {
637
647
  return this.view
638
- .deselectSource();
648
+ .deselectElement();
639
649
  };
640
650
 
641
651
  Peaks.prototype._addWindowResizeHandler = function() {
package/src/mode-layer.js CHANGED
@@ -61,22 +61,32 @@ define([
61
61
  stage.add(this._layer);
62
62
  };
63
63
 
64
- ModeLayer.prototype.selectSourceGroup = function(sourceGroup, notify) {
65
- this.deselectSourceGroup();
66
- if (sourceGroup) {
67
- this._selectedElement = sourceGroup;
64
+ ModeLayer.prototype.selectElement = function(element, notify) {
65
+ this.deselectElement(notify);
66
+ if (element) {
67
+ this._selectedElement = element;
68
68
  this._selectedElement.setSelected(true);
69
69
  if (notify) {
70
- this._peaks.emit('source.selected', this._selectedElement.getSource());
70
+ if (element instanceof SourceGroup) {
71
+ this._peaks.emit('source.selected', this._selectedElement.getSource());
72
+ }
73
+ else {
74
+ this._peaks.emit('segment.selected', this._selectedElement.getSegment());
75
+ }
71
76
  }
72
77
  }
73
78
  };
74
79
 
75
- ModeLayer.prototype.deselectSourceGroup = function(notify) {
80
+ ModeLayer.prototype.deselectElement = function(notify) {
76
81
  if (this._selectedElement) {
77
82
  this._selectedElement.setSelected(false);
78
83
  if (notify) {
79
- this._peaks.emit('source.deselected', this._selectedElement.getSource());
84
+ if (this._selectedElement instanceof SourceGroup) {
85
+ this._peaks.emit('source.deselected', this._selectedElement.getSource());
86
+ }
87
+ else {
88
+ this._peaks.emit('segment.deselected', this._selectedElement.getSegment());
89
+ }
80
90
  }
81
91
  this._selectedElement = null;
82
92
  }
@@ -140,16 +150,27 @@ define([
140
150
  var hoveredElement = this._view.getHoveredElement();
141
151
 
142
152
  if (hoveredElement) {
143
- this.selectSourceGroup(hoveredElement, true);
153
+ this.selectElement(hoveredElement, true);
144
154
  }
145
155
  else {
146
- this.deselectSourceGroup(true);
156
+ this.deselectElement(true);
147
157
  }
148
158
  };
149
159
 
150
160
  ModeLayer.prototype._onKeyboardDelete = function() {
151
161
  if (this._selectedElement) {
152
- this._peaks.destroySource(this._selectedElement.getSource().id);
162
+ var selectedElement = this._selectedElement;
163
+
164
+ this.deselectElement(true);
165
+
166
+ if (selectedElement instanceof SourceGroup) {
167
+ this._peaks.destroySource(selectedElement.getSource().id);
168
+ }
169
+ else {
170
+ if (selectedElement.getSegment().allowDeletion) {
171
+ this._peaks.destroySegment(selectedElement.getSegment().id);
172
+ }
173
+ }
153
174
  }
154
175
  };
155
176
 
@@ -318,7 +339,7 @@ define([
318
339
  break;
319
340
  }
320
341
 
321
- this.deselectSourceGroup(true);
342
+ this.deselectElement(true);
322
343
 
323
344
  // Set new mode
324
345
  switch (mode) {
@@ -26,10 +26,10 @@ define([
26
26
  * is shown next to the playhead.
27
27
  */
28
28
 
29
- function PlayheadLayer(peaks, view, segmentsGroup, showTime) {
29
+ function PlayheadLayer(peaks, view, lines, showTime) {
30
30
  this._peaks = peaks;
31
31
  this._view = view;
32
- this._segmentsGroup = segmentsGroup;
32
+ this._lines = lines;
33
33
  this._playheadPixel = 0;
34
34
  this._playheadLineAnimation = null;
35
35
  this._playheadVisible = false;
@@ -38,8 +38,8 @@ define([
38
38
 
39
39
  this._playheadLayer = new Konva.Layer();
40
40
 
41
- this._activeSegment = null;
42
- this._lastActiveSegmentId = null;
41
+ this._activeSegments = {};
42
+ this._lastActiveSegments = {};
43
43
 
44
44
  this._createPlayhead(this._playheadColor);
45
45
 
@@ -56,22 +56,26 @@ define([
56
56
  }
57
57
 
58
58
  PlayheadLayer.prototype._onSegmentsRemoveAll = function() {
59
- this._activeSegment = null;
60
- this._lastActiveSegmentId = null;
59
+ this._activeSegments = {};
60
+ this._lastActiveSegments = {};
61
61
  };
62
62
 
63
63
  PlayheadLayer.prototype._onSegmentsRemove = function(segments) {
64
- if (this._activeSegment || this._lastActiveSegmentId) {
65
- var activeSegmentId = this._activeSegment ? this._activeSegment.id : null;
66
- var lastActiveSegmentId = this._lastActiveSegmentId ? this._lastActiveSegmentId.id : null;
67
-
64
+ if (this._activeSegments || this._lastActiveSegments) {
68
65
  for (var id in segments) {
69
66
  if (Utils.objectHasProperty(segments, id)) {
67
+ var activeSegmentId = this._activeSegments[segments[id].line] ?
68
+ this._activeSegments[segments[id].line].id :
69
+ null;
70
+ var lastActiveSegmentId = this._lastActiveSegments[segments[id].line] ?
71
+ this._lastActiveSegments[segments[id].line].id :
72
+ null;
73
+
70
74
  if (segments[id].id === activeSegmentId) {
71
- this._activeSegment = null;
75
+ delete this._activeSegments[segments[id].line];
72
76
  }
73
77
  if (segments[id].id === lastActiveSegmentId) {
74
- this._lastActiveSegmentId = null;
78
+ delete this._lastActiveSegments[segments[id].line];
75
79
  }
76
80
  }
77
81
  }
@@ -279,21 +283,27 @@ define([
279
283
  var playheadPositionDiff = this._playheadGroup.x() - playheadX;
280
284
 
281
285
  if (playheadPositionDiff) {
282
- var newActiveSegment = this._segmentsGroup.getActiveSegment(
283
- this._view.pixelsToTime(playheadX + frameOffset),
284
- null,
285
- true
286
- );
286
+ var segmentsGroup = this._lines.getSegmentsGroups();
287
+
288
+ for (var lineId in segmentsGroup) {
289
+ if (Utils.objectHasProperty(segmentsGroup, lineId)) {
290
+ var newActiveSegment = segmentsGroup[lineId].getActiveSegment(
291
+ this._view.pixelsToTime(playheadX + frameOffset),
292
+ null,
293
+ true
294
+ );
287
295
 
288
- if (newActiveSegment !== this._activeSegment) {
289
- if (this._activeSegment) {
290
- this._peaks.emit('segments.exit', this._activeSegment);
291
- this._activeSegment = null;
292
- }
293
- if (newActiveSegment) {
294
- this._peaks.emit('segments.enter', newActiveSegment);
295
- this._activeSegment = newActiveSegment;
296
- this._lastActiveSegment = this._activeSegment;
296
+ if (newActiveSegment !== this._activeSegments[lineId]) {
297
+ if (this._activeSegments[lineId]) {
298
+ this._peaks.emit('segments.exit', this._activeSegments[lineId]);
299
+ delete this._activeSegments[lineId];
300
+ }
301
+ if (newActiveSegment) {
302
+ this._peaks.emit('segments.enter', newActiveSegment);
303
+ this._activeSegments[lineId] = newActiveSegment;
304
+ this._lastActiveSegments[lineId] = this._activeSegments[lineId];
305
+ }
306
+ }
297
307
  }
298
308
  }
299
309
  }
@@ -39,6 +39,7 @@ define([
39
39
  this._startMarker = null;
40
40
  this._endMarker = null;
41
41
  this._rectangle = null;
42
+ this._isSelected = false;
42
43
 
43
44
  this._segmentHeight = this._peaks.options.segmentHeight;
44
45
 
@@ -244,7 +245,9 @@ define([
244
245
  SegmentShape.prototype._onMouseEnter = function() {
245
246
  this._view.setCursor('pointer');
246
247
 
247
- this._rectangle.fill(this._segment.selectedColor + Math.round(
248
+ this._view.setHoveredElement(this);
249
+
250
+ this._rectangle.fill(this._segment.activeColor + Math.round(
248
251
  this._segment.opacity * 255
249
252
  ).toString(16));
250
253
 
@@ -256,6 +259,8 @@ define([
256
259
  SegmentShape.prototype._onMouseLeave = function() {
257
260
  this._view.setCursor('default');
258
261
 
262
+ this._view.setHoveredElement(null);
263
+
259
264
  this._rectangle.fill(this._segment.color + Math.round(
260
265
  this._segment.opacity * 255
261
266
  ).toString(16));
@@ -315,6 +320,10 @@ define([
315
320
  this._peaks.emit('segments.dragend', this._segment, startMarker);
316
321
  };
317
322
 
323
+ SegmentShape.prototype.setSelected = function(isSelected) {
324
+ this._isSelected = isSelected;
325
+ };
326
+
318
327
  SegmentShape.prototype.fitToView = function() {
319
328
  if (this._startMarker) {
320
329
  this._startMarker.fitToView();
package/src/segment.js CHANGED
@@ -50,6 +50,10 @@ define([
50
50
  else if (!Utils.isString(options.labelText)) {
51
51
  throw new TypeError('peaks.segments.' + context + ': labelText must be a string');
52
52
  }
53
+
54
+ if (!Utils.isInteger(options.line)) {
55
+ throw new TypeError('peaks.segments.' + context + ': line must be an integer');
56
+ }
53
57
  }
54
58
 
55
59
  /**
@@ -70,7 +74,7 @@ define([
70
74
  */
71
75
 
72
76
  function Segment(peaks, id, startTime, endTime, labelText, color,
73
- textColor, handleTextColor, opacity, editable) {
77
+ textColor, handleTextColor, opacity, editable, allowDeletion, line) {
74
78
  var opts = {
75
79
  startTime: startTime,
76
80
  endTime: endTime,
@@ -79,7 +83,9 @@ define([
79
83
  textColor: textColor,
80
84
  handleTextColor: handleTextColor,
81
85
  opacity: opacity,
82
- editable: editable
86
+ editable: editable,
87
+ allowDeletion: allowDeletion,
88
+ line: line
83
89
  };
84
90
 
85
91
  validateSegment(peaks, opts, 'add()');
@@ -90,11 +96,13 @@ define([
90
96
  this._endTime = opts.endTime;
91
97
  this._labelText = opts.labelText;
92
98
  this._color = opts.color;
93
- this._selectedColor = Utils.shadeColor(color, 20);
99
+ this._activeColor = Utils.shadeColor(color, 20);
94
100
  this._textColor = opts.textColor;
95
101
  this._handleTextColor = opts.handleTextColor;
96
102
  this._opacity = opts.opacity;
97
103
  this._editable = opts.editable;
104
+ this._allowDeletion = opts.allowDeletion;
105
+ this._line = opts.line;
98
106
  this._minSize = peaks.options.minSegmentSize;
99
107
  }
100
108
 
@@ -137,10 +145,10 @@ define([
137
145
  return this._color;
138
146
  }
139
147
  },
140
- selectedColor: {
148
+ activeColor: {
141
149
  enumerable: true,
142
150
  get: function() {
143
- return this._selectedColor;
151
+ return this._activeColor;
144
152
  }
145
153
  },
146
154
  textColor: {
@@ -167,6 +175,18 @@ define([
167
175
  return this._editable;
168
176
  }
169
177
  },
178
+ allowDeletion: {
179
+ enumerable: true,
180
+ get: function() {
181
+ return this._allowDeletion;
182
+ }
183
+ },
184
+ line: {
185
+ enumerable: true,
186
+ get: function() {
187
+ return this._line;
188
+ }
189
+ },
170
190
  minSize: {
171
191
  enumerable: true,
172
192
  get: function() {
@@ -184,7 +204,9 @@ define([
184
204
  textColor: this.textColor,
185
205
  handleTextColor: this.handleTextColor,
186
206
  opacity: this.opacity,
187
- editable: this.editable
207
+ editable: this.editable,
208
+ allowDeletion: this.allowDeletion,
209
+ line: this.line
188
210
  };
189
211
 
190
212
  Utils.extend(opts, options);
@@ -199,6 +221,8 @@ define([
199
221
  this._handleTextColor = opts.handleTextColor;
200
222
  this._opacity = opts.opacity;
201
223
  this._editable = opts.editable;
224
+ this._allowDeletion = opts.allowDeletion;
225
+ this._line = opts.line;
202
226
 
203
227
  this._peaks.emit('segment.updated', this);
204
228
  };
@@ -44,11 +44,6 @@ define([
44
44
 
45
45
  this._isMagnetized = false;
46
46
 
47
- this._peaks.on('segment.updated', this._onSegmentsUpdate.bind(this));
48
- this._peaks.on('segments.add', this._onSegmentsAdd.bind(this));
49
- this._peaks.on('segments.remove', this._onSegmentsRemove.bind(this));
50
- this._peaks.on('segments.remove_all', this._onSegmentsRemoveAll.bind(this));
51
- this._peaks.on('segments.dragend', this._onSegmentUpdated.bind(this));
52
47
  this._peaks.on('segments.setMagnetizing', this.setMagnetizing.bind(this));
53
48
  }
54
49
 
@@ -112,7 +107,7 @@ define([
112
107
  return activeSegment;
113
108
  };
114
109
 
115
- SegmentsGroup.prototype._onSegmentsUpdate = function(segment) {
110
+ SegmentsGroup.prototype.onSegmentsUpdate = function(segment) {
116
111
  if (this._segments[segment.id]) {
117
112
  var redraw = false;
118
113
  var segmentShape = this._segmentShapes[segment.id];
@@ -140,12 +135,12 @@ define([
140
135
  }
141
136
  };
142
137
 
143
- SegmentsGroup.prototype._onSegmentUpdated = function() {
138
+ SegmentsGroup.prototype.onSegmentUpdated = function() {
144
139
  this._peaks.emit('segments.updated', this._updatedSegments);
145
140
  this._updatedSegments = [];
146
141
  };
147
142
 
148
- SegmentsGroup.prototype._onSegmentsAdd = function(segments) {
143
+ SegmentsGroup.prototype.onSegmentsAdd = function(segments) {
149
144
  var self = this;
150
145
 
151
146
  var frameOffset = self._view.getFrameOffset();
@@ -161,7 +156,7 @@ define([
161
156
  self.updateSegments(frameStartTime, frameEndTime);
162
157
  };
163
158
 
164
- SegmentsGroup.prototype._onSegmentsRemove = function(segments) {
159
+ SegmentsGroup.prototype.onSegmentsRemove = function(segments) {
165
160
  var self = this;
166
161
 
167
162
  segments.forEach(function(segment) {
@@ -178,7 +173,7 @@ define([
178
173
  this._draw();
179
174
  };
180
175
 
181
- SegmentsGroup.prototype._onSegmentsRemoveAll = function() {
176
+ SegmentsGroup.prototype.onSegmentsRemoveAll = function() {
182
177
  this._group.removeChildren();
183
178
  this._firstSegmentId = null;
184
179
  this._segments = {};
@@ -313,7 +308,7 @@ define([
313
308
 
314
309
  SegmentsGroup.prototype.updateSegments = function(startTime, endTime) {
315
310
  // Update segments in visible time range.
316
- var segments = this._peaks.segments.find(startTime, endTime);
311
+ var segments = this.find(startTime, endTime);
317
312
 
318
313
  var count = segments.length;
319
314
 
@@ -327,6 +322,29 @@ define([
327
322
  }
328
323
  };
329
324
 
325
+ SegmentsGroup.prototype.find = function(startTime, endTime) {
326
+ var currentSegment = null;
327
+ var visibleSegments = [];
328
+
329
+ do {
330
+ if (!currentSegment) {
331
+ currentSegment = this._segments[this._firstSegmentId];
332
+ }
333
+ else {
334
+ currentSegment = this._segments[currentSegment.nextSegmentId];
335
+ }
336
+
337
+ if (currentSegment.segment.isVisible(startTime, endTime)) {
338
+ visibleSegments.push(currentSegment.segment);
339
+ }
340
+ else if (visibleSegments.length) {
341
+ break;
342
+ }
343
+ } while (currentSegment.nextSegmentId);
344
+
345
+ return visibleSegments;
346
+ };
347
+
330
348
  SegmentsGroup.prototype._draw = function() {
331
349
  this._view.drawSourcesLayer();
332
350
  };
@@ -693,11 +711,7 @@ define([
693
711
  };
694
712
 
695
713
  SegmentsGroup.prototype.destroy = function() {
696
- this._peaks.off('segment.updated', this._onSegmentsUpdate);
697
- this._peaks.off('segments.add', this._onSegmentsAdd);
698
- this._peaks.off('segments.remove', this._onSegmentsRemove);
699
- this._peaks.off('segments.remove_all', this._onSegmentsRemoveAll);
700
- this._peaks.off('segments.dragged', this._onSegmentsDragged);
714
+ this._peaks.off('segments.setMagnetizing', this.setMagnetizing);
701
715
  };
702
716
 
703
717
  SegmentsGroup.prototype.fitToView = function() {
@@ -8,7 +8,6 @@
8
8
 
9
9
  define([
10
10
  './source-group',
11
- './segments-group',
12
11
  './lines',
13
12
  './data-retriever',
14
13
  './utils',
@@ -16,7 +15,6 @@ define([
16
15
  'konva'
17
16
  ], function(
18
17
  SourceGroup,
19
- SegmentsGroup,
20
18
  Lines,
21
19
  DataRetriever,
22
20
  Utils,
@@ -45,8 +43,6 @@ define([
45
43
  this._lines = new Lines(peaks, view, this);
46
44
  this._lines.addToLayer(this);
47
45
 
48
- this._segmentsGroup = new SegmentsGroup(peaks, view, true);
49
-
50
46
  this._loadedData = {};
51
47
 
52
48
  this._debouncedRescale = new Invoker().debounce(
@@ -72,8 +68,8 @@ define([
72
68
  this._loadedData[id] = data;
73
69
  };
74
70
 
75
- SourcesLayer.prototype.getSegmentsGroup = function() {
76
- return this._segmentsGroup;
71
+ SourcesLayer.prototype.getSegmentsGroups = function() {
72
+ return this._lines.getSegmentsGroups();
77
73
  };
78
74
 
79
75
  SourcesLayer.prototype.add = function(element) {
@@ -242,8 +238,8 @@ define([
242
238
  this._layer.draw();
243
239
  };
244
240
 
245
- SourcesLayer.prototype._onSegmentsShow = function(position) {
246
- this._lines.addSegments(this._segmentsGroup, position);
241
+ SourcesLayer.prototype._onSegmentsShow = function(lineId, position) {
242
+ this._lines.addSegments(lineId, position);
247
243
  this._view.updateTimelineLength();
248
244
  this._layer.draw();
249
245
  };
@@ -136,7 +136,9 @@ define([
136
136
  options.textColor || '#000000',
137
137
  options.handleTextColor || '#000000',
138
138
  options.opacity || 1,
139
- true // editable
139
+ true, // editable
140
+ options.allowDeletion || false,
141
+ options.line
140
142
  );
141
143
 
142
144
  return segment;
@@ -156,8 +158,8 @@ define([
156
158
  * Add segments to the given line so they can be displayed.
157
159
  */
158
160
 
159
- TimelineSegments.prototype.addSegmentsToPosition = function(position) {
160
- this._peaks.emit('segments.show', position);
161
+ TimelineSegments.prototype.addSegmentsToPosition = function(lineId, position) {
162
+ this._peaks.emit('segments.show', lineId, position);
161
163
  };
162
164
 
163
165
  /**
@@ -379,10 +381,10 @@ define([
379
381
  * <code>segments.remove_all</code> event.
380
382
  */
381
383
 
382
- TimelineSegments.prototype.removeAll = function() {
384
+ TimelineSegments.prototype.removeAll = function(lineId) {
383
385
  this._segments = [];
384
386
  this._segmentsById = {};
385
- this._peaks.emit('segments.remove_all');
387
+ this._peaks.emit('segments.remove_all', lineId);
386
388
  };
387
389
 
388
390
  return TimelineSegments;
@@ -131,7 +131,7 @@ define([
131
131
  self._playheadLayer = new PlayheadLayer(
132
132
  peaks,
133
133
  self,
134
- self._sourcesLayer.getSegmentsGroup(),
134
+ self._sourcesLayer,
135
135
  self._options.showPlayheadTime
136
136
  );
137
137
 
@@ -365,12 +365,12 @@ define([
365
365
  var sourceGroup = this._sourcesLayer.getSourceGroupById(sourceId);
366
366
 
367
367
  if (sourceGroup) {
368
- this._modeLayer.selectSourceGroup(sourceGroup, false);
368
+ this._modeLayer.selectElement(sourceGroup, false);
369
369
  }
370
370
  };
371
371
 
372
- TimelineZoomView.prototype.deselectSource = function() {
373
- this._modeLayer.deselectSourceGroup(false);
372
+ TimelineZoomView.prototype.deselectElement = function() {
373
+ this._modeLayer.deselectElement(false);
374
374
  };
375
375
 
376
376
  TimelineZoomView.prototype.isListening = function() {