Skip to content

Commit

Permalink
feat(labels): labels can be deleted
Browse files Browse the repository at this point in the history
  • Loading branch information
philippfromme committed May 3, 2018
1 parent 655e75e commit e5a4396
Show file tree
Hide file tree
Showing 34 changed files with 464 additions and 416 deletions.
58 changes: 50 additions & 8 deletions lib/features/label-editing/LabelEditingProvider.js
Expand Up @@ -6,10 +6,20 @@ import {
getLabel
} from './LabelUtil';

import { Label } from 'diagram-js/lib/model';

import TextUtil from 'diagram-js/lib/util/Text';

import { is } from '../../util/ModelUtil';
import { isAny } from '../modeling/util/ModelingUtil';
import { isExpanded } from '../../util/DiUtil';

import {
getExternalLabelMid,
hasExternalLabel,
hasExternalLabelShape
} from '../../util/LabelUtil';

var SMALL_FONT_SIZE = 11,
SMALL_LINE_HEIGHT = 13,
MEDIUM_FONT_SIZE = 12,
Expand All @@ -20,6 +30,8 @@ export default function LabelEditingProvider(
eventBus, canvas, directEditing,
modeling, resizeHandles) {

this._textUtil = new TextUtil();

this._canvas = canvas;
this._modeling = modeling;

Expand Down Expand Up @@ -131,9 +143,6 @@ LabelEditingProvider.prototype.activate = function(element) {

assign(context, bounds);

// options
var target = element.label || element;

var options = {};

// tasks
Expand All @@ -152,7 +161,7 @@ LabelEditingProvider.prototype.activate = function(element) {
}

// external labels
if (target.labelTarget) {
if (hasExternalLabel(element)) {
assign(options, {
autoResize: true
});
Expand Down Expand Up @@ -268,13 +277,12 @@ LabelEditingProvider.prototype.getEditingBBox = function(element) {
});
}

var width = 90 * zoom,
paddingTop = 7 * zoom,
paddingBottom = 4 * zoom;

// external labels for events, data elements, gateways and connections
if (target.labelTarget) {
var width = 90 * zoom,
paddingTop = 7 * zoom,
paddingBottom = 4 * zoom;

assign(bounds, {
width: width,
height: bbox.height + paddingTop + paddingBottom,
Expand All @@ -290,6 +298,36 @@ LabelEditingProvider.prototype.getEditingBBox = function(element) {
});
}

// external label not yet created
if (hasExternalLabel(target)
&& !hasExternalLabelShape(target)
&& !isLabel(target)) {

var externalLabelMid = getExternalLabelMid(element);

var absoluteBBox = canvas.getAbsoluteBBox({
x: externalLabelMid.x,
y: externalLabelMid.y,
width: 0,
height: 0
});

var height = smallFontSize + paddingTop + paddingBottom;

assign(bounds, {
width: width,
height: height,
x: absoluteBBox.x - width / 2,
y: absoluteBBox.y - height / 2
});

assign(style, {
fontSize: smallFontSize + 'px',
lineHeight: smallLineHeight + 'px',
paddingTop: paddingTop + 'px',
paddingBottom: paddingBottom + 'px'
});
}

// text annotations
if (is(element, 'bpmn:TextAnnotation')) {
Expand Down Expand Up @@ -355,4 +393,8 @@ function isCollapsedPool(element) {

function isExpandedPool(element) {
return is(element, 'bpmn:Participant') && isExpanded(element);
}

function isLabel(element) {
return element instanceof Label;
}
5 changes: 0 additions & 5 deletions lib/features/label-editing/LabelUtil.js
Expand Up @@ -33,10 +33,5 @@ export function setLabel(element, text, isExternal) {
semantic[attr] = text;
}

// show external label if not empty
if (isExternal) {
element.hidden = !text;
}

return element;
}
45 changes: 44 additions & 1 deletion lib/features/label-editing/cmd/UpdateLabelHandler.js
Expand Up @@ -6,14 +6,18 @@ import {
import TextUtil from 'diagram-js/lib/util/Text';

import {
hasExternalLabel
getExternalLabelMid,
hasExternalLabel,
hasExternalLabelShape
} from '../../../util/LabelUtil';

import {
getBusinessObject,
is
} from '../../../util/ModelUtil';

import { Label } from 'diagram-js/lib/model';

var NULL_DIMENSIONS = {
width: 0,
height: 0
Expand Down Expand Up @@ -47,6 +51,33 @@ export default function UpdateLabelHandler(modeling) {
return [ label, labelTarget ];
}

function preExecute(ctx) {
var element = ctx.element,
businessObject = element.businessObject,
newLabel = ctx.newLabel;

if (!isLabel(element)
&& hasExternalLabel(element)
&& !hasExternalLabelShape(element)
&& newLabel !== '') {

// create label
var paddingTop = 7;

var labelCenter = getExternalLabelMid(element);

labelCenter = {
x: labelCenter.x,
y: labelCenter.y + paddingTop
};

modeling.createLabel(element, labelCenter, {
id: businessObject.id + '_label',
businessObject: businessObject
});
}
}

function execute(ctx) {
ctx.oldLabel = getLabel(ctx.element);
return setText(ctx.element, ctx.newLabel);
Expand All @@ -59,8 +90,15 @@ export default function UpdateLabelHandler(modeling) {
function postExecute(ctx) {
var element = ctx.element,
label = element.label || element,
newLabel = ctx.newLabel,
newBounds = ctx.newBounds;

if (isLabel(label) && newLabel.trim() === '') {
modeling.removeShape(label);

return;
}

// ignore internal labels for elements except text annotations
if (!hasExternalLabel(element) && !is(element, 'bpmn:TextAnnotation')) {
return;
Expand Down Expand Up @@ -89,6 +127,7 @@ export default function UpdateLabelHandler(modeling) {

// API

this.preExecute = preExecute;
this.execute = execute;
this.revert = revert;
this.postExecute = postExecute;
Expand Down Expand Up @@ -123,4 +162,8 @@ function getLayoutedBounds(bounds, text, textUtil) {
width: Math.ceil(layoutedLabelDimensions.width),
height: Math.ceil(layoutedLabelDimensions.height)
};
}

function isLabel(element) {
return element instanceof Label;
}
Expand Up @@ -11,7 +11,7 @@ import {
} from 'diagram-js/lib/util/Math';

import {
hasExternalLabel
hasExternalLabelShape
} from '../../../util/LabelUtil';

import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
Expand Down Expand Up @@ -50,8 +50,8 @@ export default function AdaptiveLabelPositioningBehavior(eventBus, modeling) {

function checkLabelAdjustment(element) {

// skip hidden or non-existing labels
if (!hasExternalLabel(element)) {
// skip non-existing labels
if (!hasExternalLabelShape(element)) {
return;
}

Expand Down
64 changes: 34 additions & 30 deletions lib/features/modeling/behavior/LabelBehavior.js
Expand Up @@ -43,9 +43,18 @@ export default function LabelBehavior(eventBus, modeling, bpmnFactory) {

var textUtil = new TextUtil();

// update label if name property was updated
this.postExecute('element.updateProperties', function(e) {
var context = e.context,
element = context.element,
properties = context.properties;

if (name in properties) {
modeling.updateLabel(element, name);
}
});

// create external labels on shape creation

// create label shape after shape/connection was created
this.postExecute([ 'shape.create', 'connection.create' ], function(e) {
var context = e.context;

Expand All @@ -56,6 +65,11 @@ export default function LabelBehavior(eventBus, modeling, bpmnFactory) {
return;
}

// only create label if name
if (!businessObject.name) {
return;
}

var labelCenter = getExternalLabelMid(element);

// we don't care about x and y
Expand All @@ -67,19 +81,28 @@ export default function LabelBehavior(eventBus, modeling, bpmnFactory) {

modeling.createLabel(element, labelCenter, {
id: businessObject.id + '_label',
hidden: !businessObject.name,
businessObject: businessObject,
width: labelDimensions.width,
height: labelDimensions.height
});
});

// update label after label shape was deleted
this.postExecute('shape.delete', function(event) {
var context = event.context,
shape = context;

// update di information on label creation
// check if label
if (shape.labelTarget) {
modeling.updateLabel(shape.labelTarget, '');
}
});

this.executed([ 'label.create' ], function(event) {
// update di information on label creation
this.postExecute([ 'label.create' ], function(event) {

var element = event.context.shape,
var context = event.context,
element = context.shape,
businessObject,
di;

Expand Down Expand Up @@ -111,23 +134,6 @@ export default function LabelBehavior(eventBus, modeling, bpmnFactory) {
});
});


// update label position on connection change

function getHiddenLabelAdjustment(event) {

var context = event.context,
connection = context.connection,
label = connection.label;

var labelPosition = getExternalLabelMid(connection);

return {
x: labelPosition.x - label.x - label.width / 2,
y: labelPosition.y - label.y - label.height / 2
};
}

function getVisibleLabelAdjustment(event) {

var command = event.command,
Expand Down Expand Up @@ -164,26 +170,24 @@ export default function LabelBehavior(eventBus, modeling, bpmnFactory) {
return;
}

if (label.hidden) {
labelAdjustment = getHiddenLabelAdjustment(event);
} else {
labelAdjustment = getVisibleLabelAdjustment(event);
}
labelAdjustment = getVisibleLabelAdjustment(event);

modeling.moveShape(label, labelAdjustment);
});


// keep label position on shape replace

this.postExecute([ 'shape.replace' ], function(event) {
var context = event.context,
newShape = context.newShape,
oldShape = context.oldShape;

var businessObject = getBusinessObject(newShape);

if (businessObject && hasExternalLabel(businessObject)) {
if (businessObject
&& hasExternalLabel(businessObject)
&& oldShape.label
&& newShape.label) {
newShape.label.x = oldShape.label.x;
newShape.label.y = oldShape.label.y;
}
Expand Down
7 changes: 0 additions & 7 deletions lib/features/modeling/cmd/UpdatePropertiesHandler.js
Expand Up @@ -96,13 +96,6 @@ UpdatePropertiesHandler.prototype.execute = function(context) {
}
}

if (NAME in properties && element.label) {
changed.push(element.label);

// show the label
element.label.hidden = !properties[NAME];
}

// update properties
setProperties(businessObject, properties);

Expand Down
8 changes: 0 additions & 8 deletions lib/features/rules/BpmnRules.js
Expand Up @@ -165,14 +165,6 @@ BpmnRules.prototype.init = function() {

return canPaste(tree, target);
});

this.addRule([ 'elements.delete' ], function(context) {

// do not allow deletion of labels
return filter(context.elements, function(e) {
return !isLabel(e);
});
});
};

BpmnRules.prototype.canConnectMessageFlow = canConnectMessageFlow;
Expand Down
2 changes: 1 addition & 1 deletion lib/import/BpmnImporter.js
Expand Up @@ -166,7 +166,7 @@ BpmnImporter.prototype.add = function(semantic, parentElement) {
}));
}
// (optional) LABEL
if (hasExternalLabel(semantic)) {
if (hasExternalLabel(semantic) && semantic.name) {
this.addLabel(semantic, element);
}

Expand Down

0 comments on commit e5a4396

Please sign in to comment.