From 67f56dfbee1c7bce30d91043b5e536167236055f Mon Sep 17 00:00:00 2001 From: Chris Needham Date: Sat, 7 Sep 2024 22:35:56 +0100 Subject: [PATCH] Fix mouse click and segment insert at edge of waveform view See #545 --- src/mouse-drag-handler.js | 2 +- src/scrollbar.js | 2 +- src/segment.js | 20 +++++++++++++++++--- src/waveform-view.js | 9 +++++++-- test/helpers/input-controller.js | 4 +++- test/segment-spec.js | 15 +++++++++++++++ 6 files changed, 44 insertions(+), 8 deletions(-) diff --git a/src/mouse-drag-handler.js b/src/mouse-drag-handler.js index 34342a80..14b7772b 100644 --- a/src/mouse-drag-handler.js +++ b/src/mouse-drag-handler.js @@ -169,7 +169,7 @@ MouseDragHandler.prototype._mouseUp = function(event) { MouseDragHandler.prototype._getMousePosX = function(clientX) { const containerPos = this._stage.getContainer().getBoundingClientRect(); - return clientX - containerPos.left; + return Math.floor(clientX - containerPos.left); }; /** diff --git a/src/scrollbar.js b/src/scrollbar.js index 352ee1e0..8e7dcf10 100644 --- a/src/scrollbar.js +++ b/src/scrollbar.js @@ -178,7 +178,7 @@ Scrollbar.prototype._onScrollbarClick = function(event) { if (event.target === this._stage) { if (this._zoomview) { // Centre the scrollbox where the user clicked. - let x = Math.floor(event.evt.layerX - this._scrollboxWidth / 2); + let x = Math.floor(event.evt.offsetX - this._scrollboxWidth / 2); if (x < 0) { x = 0; diff --git a/src/segment.js b/src/segment.js index 93604c0f..60b1cccb 100644 --- a/src/segment.js +++ b/src/segment.js @@ -220,12 +220,26 @@ Segment.prototype.update = function(options) { * @param {Number} startTime The start of the time region, in seconds. * @param {Number} endTime The end of the time region, in seconds. * @returns {Boolean} - * - * @see http://wiki.c2.com/?TestIfDateRangesOverlap */ Segment.prototype.isVisible = function(startTime, endTime) { - return this.startTime < endTime && startTime < this.endTime; + // A special case, where the segment has zero duration + // and is at the start of the region. + if (this.startTime === this.endTime && this.startTime === startTime) { + return true; + } + + // Segment ends before start of region. + if (this.endTime <= startTime) { + return false; + } + + // Segment starts after end of region + if (this.startTime >= endTime) { + return false; + } + + return true; }; Segment.prototype._setStartTime = function(time) { diff --git a/src/waveform-view.js b/src/waveform-view.js index 612783a5..74576b0c 100644 --- a/src/waveform-view.js +++ b/src/waveform-view.js @@ -347,6 +347,12 @@ WaveformView.prototype._onContextMenu = function(event) { }; WaveformView.prototype._clickHandler = function(event, eventName) { + let offsetX = event.evt.offsetX; + + if (offsetX < 0) { + offsetX = 0; + } + let emitViewEvent = true; if (event.target !== this._stage) { @@ -387,8 +393,7 @@ WaveformView.prototype._clickHandler = function(event, eventName) { } if (emitViewEvent) { - const mousePosX = event.evt.layerX; - const time = this.pixelOffsetToTime(mousePosX); + const time = this.pixelOffsetToTime(offsetX); const viewName = this.getName(); this._peaks.emit(viewName + '.' + eventName, { diff --git a/test/helpers/input-controller.js b/test/helpers/input-controller.js index fcbc1148..1f15a205 100644 --- a/test/helpers/input-controller.js +++ b/test/helpers/input-controller.js @@ -32,7 +32,9 @@ InputController.prototype._dispatchMouseEvent = function(type, pos) { const event = new MouseEvent(type, { bubbles: true, clientX: this._left + pos.x, - clientY: this._top + pos.y + clientY: this._top + pos.y, + offsetX: pos.x, + offsetY: pos.y }); this._target.dispatchEvent(event); diff --git a/test/segment-spec.js b/test/segment-spec.js index da0dd5c1..112327c8 100644 --- a/test/segment-spec.js +++ b/test/segment-spec.js @@ -406,5 +406,20 @@ describe('Segment', function() { expect(segment.isVisible(10.0, 20.0)).to.equal(true); }); + + it('should return true if segment starts at time zero and has zero end time', function() { + const peaks = { emit: function() {} }; + const pid = 0; + + const segment = new Segment(peaks, pid, { + id: 'segment.1', + labelText: '', + editable: true, + startTime: 0.0, + endTime: 0.0 + }); + + expect(segment.isVisible(0.0, 10.0)).to.equal(true); + }); }); });