From 100f3fb2ee6373cd4b7ad0b76e520a1afb70887e Mon Sep 17 00:00:00 2001 From: Philipp Fromme Date: Wed, 13 Jun 2018 09:01:16 +0200 Subject: [PATCH] fix(label-behavior): text annotation resizing after text property change Depends on bpmn-io/diagram-js#259 Related to camunda/camunda-modeler#631 --- lib/draw/TextRenderer.js | 29 +++++++++++++- .../label-editing/LabelEditingProvider.js | 4 +- .../label-editing/cmd/UpdateLabelHandler.js | 2 +- .../modeling/behavior/LabelBehavior.js | 18 ++++++++- .../modeling/cmd/UpdatePropertiesHandler.js | 2 +- lib/import/BpmnImporter.js | 2 +- .../modeling/behavior/label-behavior.bpmn | 13 ++++++- test/spec/draw/TextRendererSpec.js | 30 ++++++++++++++- .../modeling/behavior/LabelBehaviorSpec.js | 38 +++++++++++++++++++ 9 files changed, 128 insertions(+), 10 deletions(-) diff --git a/lib/draw/TextRenderer.js b/lib/draw/TextRenderer.js index 0bcd8391..8df3c58b 100644 --- a/lib/draw/TextRenderer.js +++ b/lib/draw/TextRenderer.js @@ -5,6 +5,8 @@ import TextUtil from 'diagram-js/lib/util/Text'; var DEFAULT_FONT_SIZE = 12; var LINE_HEIGHT_RATIO = 1.2; +var MIN_TEXT_ANNOTATION_HEIGHT = 30; + export default function TextRenderer(config) { @@ -34,7 +36,7 @@ export default function TextRenderer(config) { * * @return {Bounds} */ - this.getLayoutedBounds = function(bounds, text) { + this.getExternalLabelBounds = function(bounds, text) { var layoutedDimensions = textUtil.getDimensions(text, { box: { @@ -56,6 +58,31 @@ export default function TextRenderer(config) { }; + /** + * Get the new bounds of text annotation. + * + * @param {Bounds} bounds + * @param {String} text + * + * @return {Bounds} + */ + this.getTextAnnotationBounds = function(bounds, text) { + + var layoutedDimensions = textUtil.getDimensions(text, { + box: bounds, + style: defaultStyle, + align: 'left-top', + padding: 5 + }); + + return { + x: bounds.x, + y: bounds.y, + width: bounds.width, + height: Math.max(MIN_TEXT_ANNOTATION_HEIGHT, Math.round(layoutedDimensions.height)) + }; + }; + /** * Create a layouted text element. * diff --git a/lib/features/label-editing/LabelEditingProvider.js b/lib/features/label-editing/LabelEditingProvider.js index 6a294505..b9a93959 100644 --- a/lib/features/label-editing/LabelEditingProvider.js +++ b/lib/features/label-editing/LabelEditingProvider.js @@ -338,9 +338,9 @@ LabelEditingProvider.prototype.getEditingBBox = function(element) { assign(style, { textAlign: 'left', - paddingTop: (7 * zoom) + 'px', + paddingTop: (5 * zoom) + 'px', paddingBottom: (7 * zoom) + 'px', - paddingLeft: (5 * zoom) + 'px', + paddingLeft: (7 * zoom) + 'px', paddingRight: (5 * zoom) + 'px', fontSize: defaultFontSize + 'px', lineHeight: defaultLineHeight diff --git a/lib/features/label-editing/cmd/UpdateLabelHandler.js b/lib/features/label-editing/cmd/UpdateLabelHandler.js index ebe92d26..7b7137dd 100644 --- a/lib/features/label-editing/cmd/UpdateLabelHandler.js +++ b/lib/features/label-editing/cmd/UpdateLabelHandler.js @@ -114,7 +114,7 @@ export default function UpdateLabelHandler(modeling, textRenderer) { // resize element based on label _or_ pre-defined bounds if (typeof newBounds === 'undefined') { - newBounds = textRenderer.getLayoutedBounds(label, text); + newBounds = textRenderer.getExternalLabelBounds(label, text); } // setting newBounds to false or _null_ will diff --git a/lib/features/modeling/behavior/LabelBehavior.js b/lib/features/modeling/behavior/LabelBehavior.js index d1c38325..436a4108 100644 --- a/lib/features/modeling/behavior/LabelBehavior.js +++ b/lib/features/modeling/behavior/LabelBehavior.js @@ -52,6 +52,22 @@ export default function LabelBehavior( if (NAME_PROPERTY in properties) { modeling.updateLabel(element, properties[NAME_PROPERTY]); } + + if ('text' in properties + && is(element, 'bpmn:TextAnnotation')) { + + var newBounds = textRenderer.getTextAnnotationBounds( + { + x: element.x, + y: element.y, + width: element.width, + height: element.height + }, + properties.text || '' + ); + + modeling.updateLabel(element, properties.text, newBounds); + } }); // create label shape after shape/connection was created @@ -73,7 +89,7 @@ export default function LabelBehavior( var labelCenter = getExternalLabelMid(element); // we don't care about x and y - var labelDimensions = textRenderer.getLayoutedBounds( + var labelDimensions = textRenderer.getExternalLabelBounds( DEFAULT_LABEL_DIMENSIONS, businessObject.name || '' ); diff --git a/lib/features/modeling/cmd/UpdatePropertiesHandler.js b/lib/features/modeling/cmd/UpdatePropertiesHandler.js index 10de4bf5..fd0a4772 100644 --- a/lib/features/modeling/cmd/UpdatePropertiesHandler.js +++ b/lib/features/modeling/cmd/UpdatePropertiesHandler.js @@ -120,7 +120,7 @@ UpdatePropertiesHandler.prototype.postExecute = function(context) { // get layouted text bounds and resize external // external label accordingly - var newLabelBounds = this._textRenderer.getLayoutedBounds(label, text); + var newLabelBounds = this._textRenderer.getExternalLabelBounds(label, text); this._modeling.resizeShape(label, newLabelBounds, NULL_DIMENSIONS); }; diff --git a/lib/import/BpmnImporter.js b/lib/import/BpmnImporter.js index 18d84233..a8b24955 100644 --- a/lib/import/BpmnImporter.js +++ b/lib/import/BpmnImporter.js @@ -237,7 +237,7 @@ BpmnImporter.prototype.addLabel = function(semantic, element) { if (text) { // get corrected bounds from actual layouted text - bounds = this._textRenderer.getLayoutedBounds(bounds, text); + bounds = this._textRenderer.getExternalLabelBounds(bounds, text); } label = this._elementFactory.createLabel(elementData(semantic, { diff --git a/test/fixtures/bpmn/features/modeling/behavior/label-behavior.bpmn b/test/fixtures/bpmn/features/modeling/behavior/label-behavior.bpmn index 1de08941..9f4a13b2 100644 --- a/test/fixtures/bpmn/features/modeling/behavior/label-behavior.bpmn +++ b/test/fixtures/bpmn/features/modeling/behavior/label-behavior.bpmn @@ -1,9 +1,13 @@ - + + + foo + + @@ -19,6 +23,13 @@ + + + + + + + diff --git a/test/spec/draw/TextRendererSpec.js b/test/spec/draw/TextRendererSpec.js index c7fd9809..66ed8a09 100644 --- a/test/spec/draw/TextRendererSpec.js +++ b/test/spec/draw/TextRendererSpec.js @@ -23,7 +23,7 @@ describe('draw - TextRenderer', function() { })); - it('should expose #getLayoutedBounds', inject(function(textRenderer) { + it('should expose #getExternalLabelBounds', inject(function(textRenderer) { // given var bounds = { @@ -34,7 +34,33 @@ describe('draw - TextRenderer', function() { }; // when - var layoutedBounds = textRenderer.getLayoutedBounds( + var layoutedBounds = textRenderer.getExternalLabelBounds( + bounds, + 'FOO\nBar\nFOOBAR' + ); + + // then + expect(layoutedBounds).to.exist; + + expect(layoutedBounds.x).to.exist; + expect(layoutedBounds.y).to.exist; + expect(layoutedBounds.width).to.exist; + expect(layoutedBounds.height).to.exist; + })); + + + it('should expose #getTextAnnotationBounds', inject(function(textRenderer) { + + // given + var bounds = { + x: 0, + y: 0, + width: 100, + height: 100 + }; + + // when + var layoutedBounds = textRenderer.getTextAnnotationBounds( bounds, 'FOO\nBar\nFOOBAR' ); diff --git a/test/spec/features/modeling/behavior/LabelBehaviorSpec.js b/test/spec/features/modeling/behavior/LabelBehaviorSpec.js index fa6ea710..cbc6f83e 100644 --- a/test/spec/features/modeling/behavior/LabelBehaviorSpec.js +++ b/test/spec/features/modeling/behavior/LabelBehaviorSpec.js @@ -333,4 +333,42 @@ describe('behavior - LabelBehavior', function() { }); + + describe('update properties', function() { + + it('should resize after updating name property', inject( + function(elementRegistry, modeling) { + + // given + var spy = sinon.spy(modeling, 'resizeShape'); + + var startEventShape = elementRegistry.get('StartEvent_1'); + + // when + modeling.updateProperties(startEventShape, { name: 'bar' }); + + // then + expect(spy).to.have.been.called; + } + )); + + + it('should resize after updating text property', inject( + function(elementRegistry, modeling) { + + // given + var spy = sinon.spy(modeling, 'resizeShape'); + + var textAnnotationShape = elementRegistry.get('TextAnnotation_1'); + + // when + modeling.updateProperties(textAnnotationShape, { text: 'bar' }); + + // then + expect(spy).to.have.been.called; + } + )); + + }); + });