chore(label-editing): ensure minimum dimensions for internal labels

* This ensures a reasonable text box dimension at lower zoom levels

Closes #610
This commit is contained in:
pedesen 2016-09-05 14:27:34 +02:00 committed by Ricardo Matias
parent 9010554282
commit 5b9dc626a6
2 changed files with 70 additions and 9 deletions

View File

@ -12,7 +12,11 @@ var LINE_HEIGHT = 14,
function LabelEditingProvider(eventBus, canvas, directEditing, commandStack) { function LabelEditingProvider(eventBus, canvas, directEditing, commandStack) {
this._canvas = canvas;
this._commandStack = commandStack;
directEditing.registerProvider(this); directEditing.registerProvider(this);
commandStack.registerHandler('element.updateLabel', UpdateLabelHandler); commandStack.registerHandler('element.updateLabel', UpdateLabelHandler);
// listen to dblclick on non-root elements // 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' ]; 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) * @return {Object} an object containing information about position and size (fixed or minimum and/or maximum)
*/ */
LabelEditingProvider.prototype.getEditingBBox = function(element) { LabelEditingProvider.prototype.getEditingBBox = function(element) {
var canvas = this._canvas;
var target = element.label || element; var target = element.label || element;
var bbox = this._canvas.getAbsoluteBBox(target); var bbox = canvas.getAbsoluteBBox(target);
var mid = { var mid = {
x: bbox.x + bbox.width / 2, x: bbox.x + bbox.width / 2,
@ -108,7 +110,8 @@ LabelEditingProvider.prototype.getEditingBBox = function(element) {
// default position // default position
var bounds = { x: bbox.x, y: bbox.y }; var bounds = { x: bbox.x, y: bbox.y };
var style = {}; var style = {},
zoom;
// adjust for expanded pools AND lanes // adjust for expanded pools AND lanes
if ((is(element, 'bpmn:Participant') && isExpanded(element)) || is(element, 'bpmn:Lane')) { 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)) (is(element, 'bpmn:Participant') && !isExpanded(element))
) { ) {
// fixed size for internal labels zoom = canvas.zoom();
bounds.width = bbox.width;
bounds.height = bbox.height; // 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);
}
} }

View File

@ -1,5 +1,7 @@
'use strict'; 'use strict';
var TestContainer = require('mocha-test-container-support');
var TestHelper = require('../../../TestHelper'); var TestHelper = require('../../../TestHelper');
/* global bootstrapViewer, inject */ /* 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 }' 'div[contenteditable=true] { line-height: 14px; font-family: Arial; font-size: 12px }'
); );
var labelEditingModule = require('../../../../lib/features/label-editing'), var labelEditingModule = require('../../../../lib/features/label-editing'),
coreModule = require('../../../../lib/core'), coreModule = require('../../../../lib/core'),
draggingModule = require('diagram-js/lib/features/dragging'); 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'); var diagramXML = require('../../../fixtures/bpmn/features/label-editing/labels.bpmn');
describe('basics', function() { describe('basics', function() {
var testModules = [ labelEditingModule, coreModule, draggingModule ]; 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)); 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);
}));
});
}); });