From 5b9dc626a6335a411490d86db4e485bf1361c7d0 Mon Sep 17 00:00:00 2001 From: pedesen Date: Mon, 5 Sep 2016 14:27:34 +0200 Subject: [PATCH] chore(label-editing): ensure minimum dimensions for internal labels * This ensures a reasonable text box dimension at lower zoom levels Closes #610 --- .../label-editing/LabelEditingProvider.js | 36 ++++++++++++---- .../label-editing/LabelEditingProviderSpec.js | 43 ++++++++++++++++++- 2 files changed, 70 insertions(+), 9 deletions(-) diff --git a/lib/features/label-editing/LabelEditingProvider.js b/lib/features/label-editing/LabelEditingProvider.js index f6b1828a..3663e8f3 100644 --- a/lib/features/label-editing/LabelEditingProvider.js +++ b/lib/features/label-editing/LabelEditingProvider.js @@ -12,7 +12,11 @@ var LINE_HEIGHT = 14, function LabelEditingProvider(eventBus, canvas, directEditing, commandStack) { + this._canvas = canvas; + this._commandStack = commandStack; + directEditing.registerProvider(this); + commandStack.registerHandler('element.updateLabel', UpdateLabelHandler); // listen to dblclick on non-root elements @@ -54,9 +58,6 @@ function LabelEditingProvider(eventBus, canvas, directEditing, commandStack) { } }); } - - this._canvas = canvas; - this._commandStack = commandStack; } LabelEditingProvider.$inject = [ 'eventBus', 'canvas', 'directEditing', 'commandStack' ]; @@ -95,10 +96,11 @@ LabelEditingProvider.prototype.activate = function(element) { * @return {Object} an object containing information about position and size (fixed or minimum and/or maximum) */ LabelEditingProvider.prototype.getEditingBBox = function(element) { + var canvas = this._canvas; var target = element.label || element; - var bbox = this._canvas.getAbsoluteBBox(target); + var bbox = canvas.getAbsoluteBBox(target); var mid = { x: bbox.x + bbox.width / 2, @@ -108,7 +110,8 @@ LabelEditingProvider.prototype.getEditingBBox = function(element) { // default position var bounds = { x: bbox.x, y: bbox.y }; - var style = {}; + var style = {}, + zoom; // adjust for expanded pools AND lanes if ((is(element, 'bpmn:Participant') && isExpanded(element)) || is(element, 'bpmn:Lane')) { @@ -129,9 +132,26 @@ LabelEditingProvider.prototype.getEditingBBox = function(element) { (is(element, 'bpmn:Participant') && !isExpanded(element)) ) { - // fixed size for internal labels - bounds.width = bbox.width; - bounds.height = bbox.height; + zoom = canvas.zoom(); + + // fixed size for internal labels: + // on high zoom levels: text box size === bbox size + // on low zoom levels: text box size === bbox size at 100% zoom + // This ensures minimum bounds at low zoom levels + if (zoom > 1) { + bounds.width = bbox.width; + bounds.height = bbox.height; + } else { + bounds.width = bbox.width / zoom; + bounds.height = bbox.height / zoom; + } + + // centering overlapping text box size at low zoom levels + if (zoom < 1) { + bounds.x = bbox.x - (bounds.width / 2 - bbox.width / 2); + bounds.y = bbox.y - (bounds.height / 2 - bbox.height / 2); + } + } diff --git a/test/spec/features/label-editing/LabelEditingProviderSpec.js b/test/spec/features/label-editing/LabelEditingProviderSpec.js index fbd2ea8a..036fcabb 100644 --- a/test/spec/features/label-editing/LabelEditingProviderSpec.js +++ b/test/spec/features/label-editing/LabelEditingProviderSpec.js @@ -1,5 +1,7 @@ 'use strict'; +var TestContainer = require('mocha-test-container-support'); + var TestHelper = require('../../../TestHelper'); /* global bootstrapViewer, inject */ @@ -9,6 +11,7 @@ TestHelper.insertCSS('diagram-js-label-editing.css', 'div[contenteditable=true] { line-height: 14px; font-family: Arial; font-size: 12px }' ); + var labelEditingModule = require('../../../../lib/features/label-editing'), coreModule = require('../../../../lib/core'), draggingModule = require('diagram-js/lib/features/dragging'); @@ -32,7 +35,6 @@ describe('features - label-editing', function() { var diagramXML = require('../../../fixtures/bpmn/features/label-editing/labels.bpmn'); - describe('basics', function() { var testModules = [ labelEditingModule, coreModule, draggingModule ]; @@ -509,6 +511,45 @@ describe('features - label-editing', function() { it('[long word] should have fixed dimensions', testTextboxSizing('empty-task', 1, 100, 80, longWord)); + describe('zoom', function() { + + var container; + + beforeEach(function() { + container = TestContainer.get(this); + }); + + it('should have fixed dimensions (low zoom)', testTextboxSizing('empty-task', 0.5, 100, 80, oneWord)); + + it('should have fixed dimensions (high zoom)', testTextboxSizing('empty-task', 1.5, 150, 120, oneWord)); + + it('should center text box position (low zoom)', inject(function(canvas, elementRegistry, directEditing) { + + // given + canvas.zoom(0.5); + + var shape = elementRegistry.get('empty-task'); + + // when + directEditing.activate(shape); + + // then + var textbox = directEditing._textbox, + gfx = elementRegistry.getGraphics('empty-task'), + shapeClientRect = gfx.node.parentNode.getBoundingClientRect(); + + var shapeRect = { + top: shapeClientRect.top - container.offsetTop, + left: shapeClientRect.left - container.offsetLeft + }; + + expect(textbox.content.offsetLeft).to.be.within(shapeRect.left - 28, shapeRect.left - 22); + expect(textbox.content.offsetTop).to.be.within(shapeRect.top - 22, shapeRect.top - 17); + + })); + + }); + });