From 734b30c0b6e39410d5ea6a53d784a2ab0a950e6c Mon Sep 17 00:00:00 2001 From: bsekachev Date: Thu, 29 Nov 2018 18:02:54 +0300 Subject: [PATCH] Some aam refactoring --- .../engine/js/attributeAnnotationMode.js | 81 +++++++--- .../static/engine/js/shapeCollection.js | 41 +++-- cvat/apps/engine/static/engine/js/shapes.js | 146 +++++------------- 3 files changed, 114 insertions(+), 154 deletions(-) diff --git a/cvat/apps/engine/static/engine/js/attributeAnnotationMode.js b/cvat/apps/engine/static/engine/js/attributeAnnotationMode.js index f0ae3cdb0ad5..84306da0b063 100644 --- a/cvat/apps/engine/static/engine/js/attributeAnnotationMode.js +++ b/cvat/apps/engine/static/engine/js/attributeAnnotationMode.js @@ -117,21 +117,11 @@ class AAMModel extends Listener { if (this._activeAAM && this._active) { let label = this._active.label; let attrId = +this._attrIdByIdx(label, this._attrNumberByLabel[label].current); - let attrInfo = window.cvat.labelsInfo.attrInfo(attrId); let [xtl, ytl, xbr, ybr] = this._bbRect(this._currentShapes[this._activeIdx].interpolation.position); this._focus(xtl - this._margin, xbr + this._margin, ytl - this._margin, ybr + this._margin); - - this._active.activeAAM = { - shape: true, - attribute: attrId, - }; - this.notify(); - - if (attrInfo.type === 'text' || attrInfo.type === 'number') { - this._active.aamAttributeFocus(); - } + this._active.activeAttribute = attrId; } else { this.notify(); @@ -140,10 +130,7 @@ class AAMModel extends Listener { _deactivate() { if (this._activeAAM && this._active) { - this._active.activeAAM = { - shape: false, - attribute: null - }; + this._active.activeAttribute = null; } } @@ -153,7 +140,6 @@ class AAMModel extends Listener { this._shapeCollection.resetActive(); this._activeAAM = true; this._updateCollection(); - this.notify(); this._activate(); } } @@ -238,26 +224,22 @@ class AAMModel extends Listener { if (!this._activeAAM || !this._active) { return; } - let label = this._active.label; let frame = window.cvat.player.frames.current; let attrId = this._attrIdByIdx(label, this._attrNumberByLabel[label].current); let attrInfo = window.cvat.labelsInfo.attrInfo(attrId); - if (key >= attrInfo.values.length) { if (attrInfo.type === 'checkbox' && key < 2) { this._active.updateAttribute(frame, attrId, !attrInfo.values[0]); } return; } - if (attrInfo.values[0] === AAMUndefinedKeyword) { if (key >= attrInfo.values.length - 1) { return; } key ++; } - this._active.updateAttribute(frame, attrId, attrInfo.values[key]); } @@ -284,6 +266,10 @@ class AAMModel extends Listener { return this._activeAAM; } + get active() { + return this._active; + } + set margin(value) { this._margin = value; } @@ -333,7 +319,6 @@ class AAMController { else { return; } - this._model.setupAttributeValue(key); }.bind(this)); @@ -361,6 +346,7 @@ class AAMView { this._aamCounter = $('#aamCounter'); this._aamHelpContainer = $('#aamHelpContainer'); this._zoomMargin = $('#aamZoomMargin'); + this._frameContent = SVG.adopt($('#frameContent')[0]); this._controller = aamController; this._zoomMargin.on('change', (e) => { @@ -370,7 +356,58 @@ class AAMView { aamModel.subscribe(this); } + _setupAAMView(active, type, pos) { + let oldRect = $('#outsideRect'); + let oldMask = $('#outsideMask'); + + if (active) { + if (oldRect.length) { + oldRect.remove(); + oldMask.remove(); + } + + let size = window.cvat.translate.box.actualToCanvas({ + x: 0, + y: 0, + width: window.cvat.player.geometry.frameWidth, + height: window.cvat.player.geometry.frameHeight + }); + + let excludeField = this._frameContent.rect(size.width, size.height).move(size.x, size.y).fill('#666'); + let includeField = null; + + if (type === 'box') { + pos = window.cvat.translate.box.actualToCanvas(pos); + includeField = this._frameContent.rect(pos.xbr - pos.xtl, pos.ybr - pos.ytl).move(pos.xtl, pos.ytl); + } + else { + pos.points = window.cvat.translate.points.actualToCanvas(pos.points); + includeField = this._frameContent.polygon(pos.points); + } + + this._frameContent.mask().add(excludeField).add(includeField).fill('black').attr('id', 'outsideMask'); + this._frameContent.rect(size.width, size.height).move(size.x, size.y).attr({ + mask: 'url(#outsideMask)', + id: 'outsideRect' + }); + + let content = $(this._frameContent.node); + let texts = content.find('.shapeText'); + for (let text of texts) { + content.append(text); + } + } + else { + oldRect.remove(); + oldMask.remove(); + } + } + onAAMUpdate(aam) { + this._setupAAMView(aam.active ? true : false, + aam.active ? aam.active.type.split('_')[1] : '', + aam.active ? aam.active.interpolate(window.cvat.player.frames.current).position : 0); + if (aam.activeAAM) { if (this._aamMenu.hasClass('hidden')) { this._trackManagement.addClass('hidden'); @@ -392,7 +429,5 @@ class AAMView { this._trackManagement.removeClass('hidden'); } } - // blur on change text attribute to other or on exit from aam - blurAllElements(); } } diff --git a/cvat/apps/engine/static/engine/js/shapeCollection.js b/cvat/apps/engine/static/engine/js/shapeCollection.js index 630b79b4f149..a13869bc872f 100644 --- a/cvat/apps/engine/static/engine/js/shapeCollection.js +++ b/cvat/apps/engine/static/engine/js/shapeCollection.js @@ -21,7 +21,6 @@ class ShapeCollectionModel extends Listener { this._groupIdx = 0; this._frame = null; this._activeShape = null; - this._activeAAMShape = null; this._lastPos = { x: 0, y: 0, @@ -95,14 +94,10 @@ class ShapeCollectionModel extends Listener { this._z_order.min = 0; if (this._activeShape) { - this._activeShape.active = false; - } - - if (this._activeAAMShape) { - this._activeAAMShape.activeAAM = { - shape: false, - attribute: null - }; + if (this._activeShape.activeAttribute != null) { + this._activeShape.activeAttribute = null; + } + this.resetActive(); } this._currentShapes = []; @@ -498,16 +493,14 @@ class ShapeCollectionModel extends Listener { // If frame was not changed and collection already interpolated (for example after pause() call) if (frame === this._frame && this._currentShapes.length) return; + if (this._activeShape) { - this._activeShape.active = false; - this._activeShape = null; - } - if (this._activeAAMShape) { - this._activeAAMShape.activeAAM = { - shape: false, - attribute: null, - }; + if (this._activeShape.activeAttribute != null) { + this._activeShape.activeAttribute = null; + } + this.resetActive(); } + this._frame = frame; this._interpolate(); if (!window.cvat.mode) { @@ -522,12 +515,15 @@ class ShapeCollectionModel extends Listener { onShapeUpdate(model) { switch (model.updateReason) { - case 'activeAAM': - if (model.activeAAM.shape) { - this._activeAAMShape = model; + case 'activeAttribute': + if (model.activeAttribute != null) { + if (this._activeShape && this._activeShape != model) { + this.resetActive(); + } + this._activeShape = model; } - else if (this._activeAAMShape === model) { - this._activeAAMShape = null; + else if (this._activeShape) { + this.resetActive(); } break; case 'activation': { @@ -1583,4 +1579,5 @@ class ShapeCollectionView { } } } + } diff --git a/cvat/apps/engine/static/engine/js/shapes.js b/cvat/apps/engine/static/engine/js/shapes.js index 4d6c79d79319..b3c1d8bd2203 100644 --- a/cvat/apps/engine/static/engine/js/shapes.js +++ b/cvat/apps/engine/static/engine/js/shapes.js @@ -31,8 +31,7 @@ class ShapeModel extends Listener { this._merging = false; this._active = false; this._selected = false; - this._activeAAM = false; - this._activeAAMAttributeId = null; + this._activeAttributeId = null; this._merge = false; this._hiddenShape = false; this._hiddenText = true; @@ -442,10 +441,6 @@ class ShapeModel extends Listener { return frame in this._positions; } - aamAttributeFocus() { - this.notify('attributeFocus'); - } - select() { if (!this._selected) { this._selected = true; @@ -524,17 +519,13 @@ class ShapeModel extends Listener { return this._active; } - set activeAAM(active) { - this._activeAAM = active.shape; - this._activeAAMAttributeId = active.attribute; - this.notify('activeAAM'); + set activeAttribute(value) { + this._activeAttributeId = value; + this.notify('activeAttribute'); } - get activeAAM() { - return { - shape: this._activeAAM, - attributeId: this._activeAAMAttributeId - }; + get activeAttribute() { + return this._activeAttributeId; } set merge(value) { @@ -2260,7 +2251,7 @@ class ShapeView extends Listener { let attrInfo = window.cvat.labelsInfo.attrInfo(attrId); if (attrInfo.type === 'radio') { let idx = attrInfo.values.indexOf(attributes[attrId].value); - this._uis.attributes[attrId][idx].click(); + this._uis.attributes[attrId][idx].checked = true; } else if (attrInfo.type === 'checkbox') { this._uis.attributes[attrId].checked = attributes[attrId].value; @@ -2469,13 +2460,13 @@ class ShapeView extends Listener { onShapeUpdate(model) { let interpolation = model.interpolate(window.cvat.player.frames.current); - let hiddenText = model.hiddenText; - let hiddenShape = model.hiddenShape; - let activeAAM = model.activeAAM; + let activeAttribute = model.activeAttribute; + let hiddenText = model.hiddenText && activeAttribute === null; + let hiddenShape = model.hiddenShape && activeAttribute === null; this._makeNotEditable(); this._deselect(); - if (hiddenText && !activeAAM.shape) { + if (hiddenText) { this._hideShapeText(); } @@ -2487,7 +2478,8 @@ class ShapeView extends Listener { break; case 'attributes': this._updateMenuContent(interpolation); - setupHidden.call(this, hiddenShape, hiddenText, activeAAM, model.active, interpolation); + setupHidden.call(this, hiddenShape, hiddenText, + activeAttribute, model.active, interpolation); break; case 'merge': this._setupMergeView(model.merge); @@ -2511,7 +2503,8 @@ class ShapeView extends Listener { this._updateButtonsBlock(interpolation.position); break; case 'hidden': - setupHidden.call(this, hiddenShape, hiddenText, activeAAM, model.active, interpolation); + setupHidden.call(this, hiddenShape, hiddenText, + activeAttribute, model.active, interpolation); this._updateButtonsBlock(interpolation.position); this.notify('hidden'); break; @@ -2543,19 +2536,22 @@ class ShapeView extends Listener { this.notify('changelabel'); break; } - case 'attributeFocus': { - let attrId = model.activeAAM.attributeId; - this._uis.attributes[attrId].focus(); - this._uis.attributes[attrId].select(); - break; - } - case 'activeAAM': - this._setupAAMView(activeAAM.shape, interpolation.position); - setupHidden.call(this, hiddenShape, hiddenText, activeAAM, model.active, interpolation); + case 'activeAttribute': + setupHidden.call(this, hiddenShape, hiddenText, + activeAttribute, model.active, interpolation); - if (activeAAM.shape && this._uis.shape) { + if (activeAttribute != null && this._uis.shape) { this._uis.shape.node.dispatchEvent(new Event('click')); - this._highlightAttribute(activeAAM.attributeId); + this._highlightAttribute(activeAttribute); + + let attrInfo = window.cvat.labelsInfo.attrInfo(activeAttribute); + if (attrInfo.type === 'text' || attrInfo.type === 'number') { + this._uis.attributes[activeAttribute].focus(); + this._uis.attributes[activeAttribute].select(); + } + else { + blurAllElements(); + } } else { this._highlightAttribute(null); @@ -2586,9 +2582,9 @@ class ShapeView extends Listener { } } - if (model.active || activeAAM.shape) { + if (model.active || activeAttribute != null) { this._select(); - if (!activeAAM.shape) { + if (activeAttribute === null) { this._makeEditable(); } } @@ -2597,25 +2593,25 @@ class ShapeView extends Listener { this._showShapeText(); } - function setupHidden(hiddenShape, hiddenText, activeAAM, active, interpolation) { + function setupHidden(hiddenShape, hiddenText, attributeId, active, interpolation) { this._makeNotEditable(); this._removeShapeUI(); this._removeShapeText(); - if (!hiddenShape || activeAAM.shape) { + if (!hiddenShape) { this._drawShapeUI(interpolation.position); this._setupOccludedUI(interpolation.position.occluded); - if (!hiddenText || active || activeAAM.shape) { + if (!hiddenText || active) { this._showShapeText(); } - if (model.active || activeAAM.shape) { + if (active || attributeId != null) { this._select(); - if (!activeAAM.shape) { + if (attributeId === null) { this._makeEditable(); } else { - this._highlightAttribute(activeAAM.attributeId); + this._highlightAttribute(attributeId); } } } @@ -2801,39 +2797,6 @@ class BoxView extends ShapeView { ShapeView.prototype._drawShapeUI.call(this); } - - _setupAAMView(active, pos) { - let oldRect = $('#outsideRect'); - let oldMask = $('#outsideMask'); - - if (active) { - if (oldRect.length) { - oldRect.remove(); - oldMask.remove(); - } - - let size = window.cvat.translate.box.actualToCanvas({ - x: 0, - y: 0, - width: window.cvat.player.geometry.frameWidth, - height: window.cvat.player.geometry.frameHeight - }); - - pos = window.cvat.translate.box.actualToCanvas(pos); - - let excludeField = this._scenes.svg.rect(size.width, size.height).move(size.x, size.y).fill('#666'); - let includeField = this._scenes.svg.rect(pos.xbr - pos.xtl, pos.ybr - pos.ytl).move(pos.xtl, pos.ytl); - this._scenes.svg.mask().add(excludeField).add(includeField).fill('black').attr('id', 'outsideMask'); - this._scenes.svg.rect(size.width, size.height).move(size.x, size.y).attr({ - mask: 'url(#outsideMask)', - id: 'outsideRect' - }); - } - else { - oldRect.remove(); - oldMask.remove(); - } - } } @@ -2852,41 +2815,6 @@ class PolyShapeView extends ShapeView { }; } - - _setupAAMView(active, pos) { - let oldRect = $('#outsideRect'); - let oldMask = $('#outsideMask'); - - if (active) { - if (oldRect.length) { - oldRect.remove(); - oldMask.remove(); - } - - let size = window.cvat.translate.box.actualToCanvas({ - x: 0, - y: 0, - width: window.cvat.player.geometry.frameWidth, - height: window.cvat.player.geometry.frameHeight - }); - - let points = window.cvat.translate.points.actualToCanvas(pos.points); - - let excludeField = this._scenes.svg.rect(size.width, size.height).move(size.x, size.y).fill('#666'); - let includeField = this._scenes.svg.polygon(points); - this._scenes.svg.mask().add(excludeField).add(includeField).fill('black').attr('id', 'outsideMask'); - this._scenes.svg.rect(size.width, size.height).move(size.x, size.y).attr({ - mask: 'url(#outsideMask)', - id: 'outsideRect' - }); - } - else { - oldRect.remove(); - oldMask.remove(); - } - } - - _makeEditable() { ShapeView.prototype._makeEditable.call(this); if (this._flags.editable) {