mirror of
https://bitbucket.org/wisemapping/wisemapping-frontend.git
synced 2024-11-14 03:07:57 +01:00
Enable eslit for mindplot
This commit is contained in:
parent
b25fe345ae
commit
9457ca6047
11
packages/mindplot/.eslintrc.json
Normal file
11
packages/mindplot/.eslintrc.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"commonjs": true
|
||||||
|
},
|
||||||
|
"extends": [
|
||||||
|
"airbnb-base"
|
||||||
|
],
|
||||||
|
"plugins": ["only-warn"],
|
||||||
|
"rules": {}
|
||||||
|
}
|
@ -17,96 +17,96 @@
|
|||||||
*/
|
*/
|
||||||
const Events = require('./Events').default;
|
const Events = require('./Events').default;
|
||||||
|
|
||||||
//noinspection JSUnusedLocalSymbols
|
// noinspection JSUnusedLocalSymbols
|
||||||
const ActionDispatcher = new Class({
|
const ActionDispatcher = new Class({
|
||||||
Implements:[Events],
|
Implements: [Events],
|
||||||
initialize: function(commandContext) {
|
initialize(commandContext) {
|
||||||
$assert(commandContext, "commandContext can not be null");
|
$assert(commandContext, 'commandContext can not be null');
|
||||||
},
|
},
|
||||||
|
|
||||||
addRelationship: function(model, mindmap) {
|
addRelationship(model, mindmap) {
|
||||||
throw "method must be implemented.";
|
throw 'method must be implemented.';
|
||||||
},
|
},
|
||||||
|
|
||||||
addTopics: function(models, parentTopicId) {
|
addTopics(models, parentTopicId) {
|
||||||
throw "method must be implemented.";
|
throw 'method must be implemented.';
|
||||||
},
|
},
|
||||||
|
|
||||||
deleteEntities: function(topicsIds, relIds) {
|
deleteEntities(topicsIds, relIds) {
|
||||||
throw "method must be implemented.";
|
throw 'method must be implemented.';
|
||||||
},
|
},
|
||||||
|
|
||||||
dragTopic: function(topicId, position, order, parentTopic) {
|
dragTopic(topicId, position, order, parentTopic) {
|
||||||
throw "method must be implemented.";
|
throw 'method must be implemented.';
|
||||||
},
|
},
|
||||||
|
|
||||||
moveTopic: function(topicId, position) {
|
moveTopic(topicId, position) {
|
||||||
throw "method must be implemented.";
|
throw 'method must be implemented.';
|
||||||
},
|
},
|
||||||
|
|
||||||
moveControlPoint: function(ctrlPoint, point) {
|
moveControlPoint(ctrlPoint, point) {
|
||||||
throw "method must be implemented.";
|
throw 'method must be implemented.';
|
||||||
},
|
},
|
||||||
|
|
||||||
changeFontFamilyToTopic: function(topicIds, fontFamily) {
|
changeFontFamilyToTopic(topicIds, fontFamily) {
|
||||||
throw "method must be implemented.";
|
throw 'method must be implemented.';
|
||||||
},
|
},
|
||||||
|
|
||||||
changeFontStyleToTopic: function(topicsIds) {
|
changeFontStyleToTopic(topicsIds) {
|
||||||
throw "method must be implemented.";
|
throw 'method must be implemented.';
|
||||||
},
|
},
|
||||||
|
|
||||||
changeFontColorToTopic: function(topicsIds, color) {
|
changeFontColorToTopic(topicsIds, color) {
|
||||||
throw "method must be implemented.";
|
throw 'method must be implemented.';
|
||||||
},
|
},
|
||||||
|
|
||||||
changeFontSizeToTopic : function(topicsIds, size) {
|
changeFontSizeToTopic(topicsIds, size) {
|
||||||
throw "method must be implemented.";
|
throw 'method must be implemented.';
|
||||||
},
|
},
|
||||||
|
|
||||||
changeBackgroundColorToTopic: function(topicsIds, color) {
|
changeBackgroundColorToTopic(topicsIds, color) {
|
||||||
throw "method must be implemented.";
|
throw 'method must be implemented.';
|
||||||
},
|
},
|
||||||
|
|
||||||
changeBorderColorToTopic: function(topicsIds, color) {
|
changeBorderColorToTopic(topicsIds, color) {
|
||||||
throw "method must be implemented.";
|
throw 'method must be implemented.';
|
||||||
},
|
},
|
||||||
|
|
||||||
changeShapeTypeToTopic : function(topicsIds, shapeType) {
|
changeShapeTypeToTopic(topicsIds, shapeType) {
|
||||||
throw "method must be implemented.";
|
throw 'method must be implemented.';
|
||||||
},
|
},
|
||||||
|
|
||||||
changeFontWeightToTopic : function(topicsIds) {
|
changeFontWeightToTopic(topicsIds) {
|
||||||
throw "method must be implemented.";
|
throw 'method must be implemented.';
|
||||||
},
|
},
|
||||||
|
|
||||||
changeTextToTopic : function(topicsIds, text) {
|
changeTextToTopic(topicsIds, text) {
|
||||||
throw "method must be implemented.";
|
throw 'method must be implemented.';
|
||||||
},
|
},
|
||||||
|
|
||||||
shrinkBranch : function(topicsIds, collapse) {
|
shrinkBranch(topicsIds, collapse) {
|
||||||
throw "method must be implemented.";
|
throw 'method must be implemented.';
|
||||||
},
|
},
|
||||||
|
|
||||||
addFeatureToTopic : function(topicId, type, attributes) {
|
addFeatureToTopic(topicId, type, attributes) {
|
||||||
throw "method must be implemented.";
|
throw 'method must be implemented.';
|
||||||
},
|
},
|
||||||
|
|
||||||
changeFeatureToTopic : function(topicId, featureId, attributes) {
|
changeFeatureToTopic(topicId, featureId, attributes) {
|
||||||
throw "method must be implemented.";
|
throw 'method must be implemented.';
|
||||||
},
|
},
|
||||||
|
|
||||||
removeFeatureFromTopic : function(topicId, featureId) {
|
removeFeatureFromTopic(topicId, featureId) {
|
||||||
throw "method must be implemented.";
|
throw 'method must be implemented.';
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
ActionDispatcher.setInstance = function(dispatcher) {
|
ActionDispatcher.setInstance = function (dispatcher) {
|
||||||
ActionDispatcher._instance = dispatcher;
|
ActionDispatcher._instance = dispatcher;
|
||||||
};
|
};
|
||||||
|
|
||||||
ActionDispatcher.getInstance = function() {
|
ActionDispatcher.getInstance = function () {
|
||||||
return ActionDispatcher._instance;
|
return ActionDispatcher._instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ActionDispatcher;
|
export default ActionDispatcher;
|
||||||
|
@ -18,47 +18,47 @@
|
|||||||
const Icon = require('./Icon').default;
|
const Icon = require('./Icon').default;
|
||||||
|
|
||||||
const ActionIcon = new Class({
|
const ActionIcon = new Class({
|
||||||
Extends:Icon,
|
Extends: Icon,
|
||||||
initialize: function(topic, url) {
|
initialize(topic, url) {
|
||||||
this.parent(url);
|
this.parent(url);
|
||||||
this._node = topic;
|
this._node = topic;
|
||||||
},
|
},
|
||||||
getNode:function() {
|
getNode() {
|
||||||
return this._node;
|
return this._node;
|
||||||
},
|
},
|
||||||
|
|
||||||
setPosition:function(x, y) {
|
setPosition(x, y) {
|
||||||
var size = this.getSize();
|
const size = this.getSize();
|
||||||
this.getImage().setPosition(x - size.width / 2, y - size.height / 2);
|
this.getImage().setPosition(x - size.width / 2, y - size.height / 2);
|
||||||
},
|
},
|
||||||
|
|
||||||
addEvent:function(event, fn) {
|
addEvent(event, fn) {
|
||||||
this.getImage().addEvent(event, fn);
|
this.getImage().addEvent(event, fn);
|
||||||
},
|
},
|
||||||
|
|
||||||
addToGroup:function(group) {
|
addToGroup(group) {
|
||||||
group.append(this.getImage());
|
group.append(this.getImage());
|
||||||
},
|
},
|
||||||
|
|
||||||
setVisibility:function(visible) {
|
setVisibility(visible) {
|
||||||
this.getImage().setVisibility(visible);
|
this.getImage().setVisibility(visible);
|
||||||
},
|
},
|
||||||
|
|
||||||
isVisible:function() {
|
isVisible() {
|
||||||
return this.getImage().isVisible();
|
return this.getImage().isVisible();
|
||||||
},
|
},
|
||||||
|
|
||||||
setCursor:function(cursor) {
|
setCursor(cursor) {
|
||||||
return this.getImage().setCursor(cursor);
|
return this.getImage().setCursor(cursor);
|
||||||
},
|
},
|
||||||
|
|
||||||
moveToBack:function(cursor) {
|
moveToBack(cursor) {
|
||||||
return this.getImage().moveToBack(cursor);
|
return this.getImage().moveToBack(cursor);
|
||||||
},
|
},
|
||||||
|
|
||||||
moveToFront:function(cursor) {
|
moveToFront(cursor) {
|
||||||
return this.getImage().moveToFront(cursor);
|
return this.getImage().moveToFront(cursor);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default ActionIcon;
|
export default ActionIcon;
|
||||||
|
@ -16,66 +16,67 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
const Core = require('@wismapping/core-js');
|
const Core = require('@wismapping/core-js');
|
||||||
|
|
||||||
const core = Core();
|
const core = Core();
|
||||||
const Topic = require('./Topic').default;
|
const Topic = require('./Topic').default;
|
||||||
const Shape = require('./util/Shape').default;
|
const Shape = require('./util/Shape').default;
|
||||||
|
|
||||||
const CentralTopic = new Class(
|
const CentralTopic = new Class(
|
||||||
/** @lends CentralTopic*/ {
|
/** @lends CentralTopic */ {
|
||||||
Extends: Topic,
|
Extends: Topic,
|
||||||
/**
|
/**
|
||||||
* @extends mindplot.Topic
|
* @extends mindplot.Topic
|
||||||
* @constructs
|
* @constructs
|
||||||
* @param model
|
* @param model
|
||||||
* @param options
|
* @param options
|
||||||
*/
|
*/
|
||||||
initialize: function (model, options) {
|
initialize(model, options) {
|
||||||
this.parent(model, options);
|
this.parent(model, options);
|
||||||
},
|
},
|
||||||
|
|
||||||
_registerEvents: function () {
|
_registerEvents() {
|
||||||
this.parent();
|
this.parent();
|
||||||
|
|
||||||
// This disable the drag of the central topic. But solves the problem of deselecting the nodes when the screen is clicked.
|
// This disable the drag of the central topic. But solves the problem of deselecting the nodes when the screen is clicked.
|
||||||
this.addEvent('mousedown', function (event) {
|
this.addEvent('mousedown', (event) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
workoutIncomingConnectionPoint: function () {
|
workoutIncomingConnectionPoint() {
|
||||||
return this.getPosition();
|
return this.getPosition();
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setCursor: function (type) {
|
setCursor(type) {
|
||||||
type = type == 'move' ? 'default' : type;
|
type = type == 'move' ? 'default' : type;
|
||||||
this.parent(type);
|
this.parent(type);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
updateTopicShape: function () {},
|
updateTopicShape() {},
|
||||||
|
|
||||||
_updatePositionOnChangeSize: function () {
|
_updatePositionOnChangeSize() {
|
||||||
// Center main topic ...
|
// Center main topic ...
|
||||||
var zeroPoint = new core.Point(0, 0);
|
const zeroPoint = new core.Point(0, 0);
|
||||||
this.setPosition(zeroPoint);
|
this.setPosition(zeroPoint);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getShrinkConnector: function () {
|
getShrinkConnector() {
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
workoutOutgoingConnectionPoint: function (targetPosition) {
|
workoutOutgoingConnectionPoint(targetPosition) {
|
||||||
$assert(targetPosition, 'targetPoint can not be null');
|
$assert(targetPosition, 'targetPoint can not be null');
|
||||||
var pos = this.getPosition();
|
const pos = this.getPosition();
|
||||||
var isAtRight = Shape.isAtRight(targetPosition, pos);
|
const isAtRight = Shape.isAtRight(targetPosition, pos);
|
||||||
var size = this.getSize();
|
const size = this.getSize();
|
||||||
return Shape.calculateRectConnectionPoint(pos, size, !isAtRight);
|
return Shape.calculateRectConnectionPoint(pos, size, !isAtRight);
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
export default CentralTopic;
|
export default CentralTopic;
|
||||||
|
@ -17,51 +17,45 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const Command = new Class(/** @lends mindplot.Command */{
|
const Command = new Class(/** @lends mindplot.Command */{
|
||||||
/**
|
/**
|
||||||
* @classdesc The command base class for handling do/undo mindmap operations
|
* @classdesc The command base class for handling do/undo mindmap operations
|
||||||
* @constructs
|
* @constructs
|
||||||
*/
|
*/
|
||||||
initialize: function()
|
initialize() {
|
||||||
{
|
this._id = Command._nextUUID();
|
||||||
this._id = Command._nextUUID();
|
},
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @abstract
|
* @abstract
|
||||||
*/
|
*/
|
||||||
execute: function(commandContext)
|
execute(commandContext) {
|
||||||
{
|
throw 'execute must be implemented.';
|
||||||
throw "execute must be implemented.";
|
},
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggered by the undo button - reverses the executed command
|
* Triggered by the undo button - reverses the executed command
|
||||||
* @abstract
|
* @abstract
|
||||||
*/
|
*/
|
||||||
undoExecute: function(commandContext)
|
undoExecute(commandContext) {
|
||||||
{
|
throw 'undo must be implemented.';
|
||||||
throw "undo must be implemented.";
|
},
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the unique id of this command
|
* Returns the unique id of this command
|
||||||
* @returns {Number} command id
|
* @returns {Number} command id
|
||||||
*/
|
*/
|
||||||
getId:function()
|
getId() {
|
||||||
{
|
return this._id;
|
||||||
return this._id;
|
},
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Command._nextUUID = function()
|
Command._nextUUID = function () {
|
||||||
{
|
if (!$defined(Command._uuid)) {
|
||||||
if (!$defined(Command._uuid))
|
Command._uuid = 1;
|
||||||
{
|
}
|
||||||
Command._uuid = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Command._uuid = Command._uuid + 1;
|
Command._uuid += 1;
|
||||||
return Command._uuid;
|
return Command._uuid;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Command;
|
export default Command;
|
||||||
|
@ -16,8 +16,10 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
const Core = require('@wismapping/core-js');
|
const Core = require('@wismapping/core-js');
|
||||||
|
|
||||||
const core = Core();
|
const core = Core();
|
||||||
const web2D = require('@wismapping/web2d');
|
const web2D = require('@wismapping/web2d');
|
||||||
|
|
||||||
const web2d = web2D();
|
const web2d = web2D();
|
||||||
|
|
||||||
const INodeModel = require('./model/INodeModel').default;
|
const INodeModel = require('./model/INodeModel').default;
|
||||||
@ -25,182 +27,184 @@ const { TopicShape } = require('./model/INodeModel');
|
|||||||
const Topic = require('./Topic').default;
|
const Topic = require('./Topic').default;
|
||||||
|
|
||||||
const ConnectionLine = new Class({
|
const ConnectionLine = new Class({
|
||||||
initialize: function (sourceNode, targetNode, lineType) {
|
initialize(sourceNode, targetNode, lineType) {
|
||||||
$assert(targetNode, 'parentNode node can not be null');
|
$assert(targetNode, 'parentNode node can not be null');
|
||||||
$assert(sourceNode, 'childNode node can not be null');
|
$assert(sourceNode, 'childNode node can not be null');
|
||||||
$assert(sourceNode != targetNode, 'Circular connection');
|
$assert(sourceNode != targetNode, 'Circular connection');
|
||||||
|
|
||||||
this._targetTopic = targetNode;
|
this._targetTopic = targetNode;
|
||||||
this._sourceTopic = sourceNode;
|
this._sourceTopic = sourceNode;
|
||||||
|
|
||||||
var line;
|
let line;
|
||||||
var ctrlPoints = this._getCtrlPoints(sourceNode, targetNode);
|
const ctrlPoints = this._getCtrlPoints(sourceNode, targetNode);
|
||||||
if (targetNode.getType() == INodeModel.CENTRAL_TOPIC_TYPE) {
|
if (targetNode.getType() == INodeModel.CENTRAL_TOPIC_TYPE) {
|
||||||
line = this._createLine(lineType, ConnectionLine.CURVED);
|
line = this._createLine(lineType, ConnectionLine.CURVED);
|
||||||
line.setSrcControlPoint(ctrlPoints[0]);
|
line.setSrcControlPoint(ctrlPoints[0]);
|
||||||
line.setDestControlPoint(ctrlPoints[1]);
|
line.setDestControlPoint(ctrlPoints[1]);
|
||||||
} else {
|
} else {
|
||||||
line = this._createLine(lineType, ConnectionLine.SIMPLE_CURVED);
|
line = this._createLine(lineType, ConnectionLine.SIMPLE_CURVED);
|
||||||
line.setSrcControlPoint(ctrlPoints[0]);
|
line.setSrcControlPoint(ctrlPoints[0]);
|
||||||
line.setDestControlPoint(ctrlPoints[1]);
|
line.setDestControlPoint(ctrlPoints[1]);
|
||||||
}
|
}
|
||||||
// Set line styles ...
|
// Set line styles ...
|
||||||
var strokeColor = ConnectionLine.getStrokeColor();
|
const strokeColor = ConnectionLine.getStrokeColor();
|
||||||
line.setStroke(1, 'solid', strokeColor, 1);
|
line.setStroke(1, 'solid', strokeColor, 1);
|
||||||
line.setFill(strokeColor, 1);
|
line.setFill(strokeColor, 1);
|
||||||
|
|
||||||
this._line2d = line;
|
this._line2d = line;
|
||||||
},
|
},
|
||||||
|
|
||||||
_getCtrlPoints: function (sourceNode, targetNode) {
|
_getCtrlPoints(sourceNode, targetNode) {
|
||||||
var srcPos = sourceNode.workoutOutgoingConnectionPoint(targetNode.getPosition());
|
const srcPos = sourceNode.workoutOutgoingConnectionPoint(targetNode.getPosition());
|
||||||
var destPos = targetNode.workoutIncomingConnectionPoint(sourceNode.getPosition());
|
const destPos = targetNode.workoutIncomingConnectionPoint(sourceNode.getPosition());
|
||||||
var deltaX = (srcPos.x - destPos.x) / 3;
|
const deltaX = (srcPos.x - destPos.x) / 3;
|
||||||
return [new core.Point(deltaX, 0), new core.Point(-deltaX, 0)];
|
return [new core.Point(deltaX, 0), new core.Point(-deltaX, 0)];
|
||||||
},
|
},
|
||||||
|
|
||||||
_createLine: function (lineType, defaultStyle) {
|
_createLine(lineType, defaultStyle) {
|
||||||
if (!$defined(lineType)) {
|
if (!$defined(lineType)) {
|
||||||
lineType = defaultStyle;
|
lineType = defaultStyle;
|
||||||
}
|
}
|
||||||
lineType = parseInt(lineType);
|
lineType = parseInt(lineType);
|
||||||
this._lineType = lineType;
|
this._lineType = lineType;
|
||||||
var line = null;
|
let line = null;
|
||||||
switch (lineType) {
|
switch (lineType) {
|
||||||
case ConnectionLine.POLYLINE:
|
case ConnectionLine.POLYLINE:
|
||||||
line = new web2d.PolyLine();
|
line = new web2d.PolyLine();
|
||||||
break;
|
break;
|
||||||
case ConnectionLine.CURVED:
|
case ConnectionLine.CURVED:
|
||||||
line = new web2d.CurvedLine();
|
line = new web2d.CurvedLine();
|
||||||
break;
|
break;
|
||||||
case ConnectionLine.SIMPLE_CURVED:
|
case ConnectionLine.SIMPLE_CURVED:
|
||||||
line = new web2d.CurvedLine();
|
line = new web2d.CurvedLine();
|
||||||
line.setStyle(web2d.CurvedLine.SIMPLE_LINE);
|
line.setStyle(web2d.CurvedLine.SIMPLE_LINE);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
line = new web2d.Line();
|
line = new web2d.Line();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return line;
|
return line;
|
||||||
},
|
},
|
||||||
|
|
||||||
setVisibility: function (value) {
|
setVisibility(value) {
|
||||||
this._line2d.setVisibility(value);
|
this._line2d.setVisibility(value);
|
||||||
},
|
},
|
||||||
|
|
||||||
isVisible: function () {
|
isVisible() {
|
||||||
return this._line2d.isVisible();
|
return this._line2d.isVisible();
|
||||||
},
|
},
|
||||||
|
|
||||||
setOpacity: function (opacity) {
|
setOpacity(opacity) {
|
||||||
this._line2d.setOpacity(opacity);
|
this._line2d.setOpacity(opacity);
|
||||||
},
|
},
|
||||||
|
|
||||||
redraw: function () {
|
redraw() {
|
||||||
var line2d = this._line2d;
|
const line2d = this._line2d;
|
||||||
var sourceTopic = this._sourceTopic;
|
const sourceTopic = this._sourceTopic;
|
||||||
var sourcePosition = sourceTopic.getPosition();
|
const sourcePosition = sourceTopic.getPosition();
|
||||||
|
|
||||||
var targetTopic = this._targetTopic;
|
const targetTopic = this._targetTopic;
|
||||||
var targetPosition = targetTopic.getPosition();
|
const targetPosition = targetTopic.getPosition();
|
||||||
|
|
||||||
var sPos, tPos;
|
let sPos; let
|
||||||
sPos = sourceTopic.workoutOutgoingConnectionPoint(targetPosition);
|
tPos;
|
||||||
tPos = targetTopic.workoutIncomingConnectionPoint(sourcePosition);
|
sPos = sourceTopic.workoutOutgoingConnectionPoint(targetPosition);
|
||||||
|
tPos = targetTopic.workoutIncomingConnectionPoint(sourcePosition);
|
||||||
|
|
||||||
line2d.setFrom(tPos.x, tPos.y);
|
line2d.setFrom(tPos.x, tPos.y);
|
||||||
line2d.setTo(sPos.x, sPos.y);
|
line2d.setTo(sPos.x, sPos.y);
|
||||||
|
|
||||||
if (line2d.getType() == 'CurvedLine') {
|
if (line2d.getType() == 'CurvedLine') {
|
||||||
var ctrlPoints = this._getCtrlPoints(this._sourceTopic, this._targetTopic);
|
const ctrlPoints = this._getCtrlPoints(this._sourceTopic, this._targetTopic);
|
||||||
line2d.setSrcControlPoint(ctrlPoints[0]);
|
line2d.setSrcControlPoint(ctrlPoints[0]);
|
||||||
line2d.setDestControlPoint(ctrlPoints[1]);
|
line2d.setDestControlPoint(ctrlPoints[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add connector ...
|
// Add connector ...
|
||||||
this._positionateConnector(targetTopic);
|
this._positionateConnector(targetTopic);
|
||||||
},
|
},
|
||||||
|
|
||||||
_positionateConnector: function (targetTopic) {
|
_positionateConnector(targetTopic) {
|
||||||
var targetPosition = targetTopic.getPosition();
|
const targetPosition = targetTopic.getPosition();
|
||||||
var offset = Topic.CONNECTOR_WIDTH / 2;
|
const offset = Topic.CONNECTOR_WIDTH / 2;
|
||||||
var targetTopicSize = targetTopic.getSize();
|
const targetTopicSize = targetTopic.getSize();
|
||||||
var y, x;
|
let y; let
|
||||||
if (targetTopic.getShapeType() == TopicShape.LINE) {
|
x;
|
||||||
y = targetTopicSize.height;
|
if (targetTopic.getShapeType() == TopicShape.LINE) {
|
||||||
} else {
|
y = targetTopicSize.height;
|
||||||
y = targetTopicSize.height / 2;
|
} else {
|
||||||
}
|
y = targetTopicSize.height / 2;
|
||||||
y = y - offset;
|
}
|
||||||
|
y -= offset;
|
||||||
|
|
||||||
var connector = targetTopic.getShrinkConnector();
|
const connector = targetTopic.getShrinkConnector();
|
||||||
if ($defined(connector)) {
|
if ($defined(connector)) {
|
||||||
if (Math.sign(targetPosition.x) > 0) {
|
if (Math.sign(targetPosition.x) > 0) {
|
||||||
x = targetTopicSize.width;
|
x = targetTopicSize.width;
|
||||||
connector.setPosition(x, y);
|
connector.setPosition(x, y);
|
||||||
} else {
|
} else {
|
||||||
x = -Topic.CONNECTOR_WIDTH;
|
x = -Topic.CONNECTOR_WIDTH;
|
||||||
}
|
}
|
||||||
connector.setPosition(x, y);
|
connector.setPosition(x, y);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setStroke: function (color, style, opacity) {
|
setStroke(color, style, opacity) {
|
||||||
this._line2d.setStroke(null, null, color, opacity);
|
this._line2d.setStroke(null, null, color, opacity);
|
||||||
},
|
},
|
||||||
|
|
||||||
addToWorkspace: function (workspace) {
|
addToWorkspace(workspace) {
|
||||||
workspace.append(this._line2d);
|
workspace.append(this._line2d);
|
||||||
this._line2d.moveToBack();
|
this._line2d.moveToBack();
|
||||||
},
|
},
|
||||||
|
|
||||||
removeFromWorkspace: function (workspace) {
|
removeFromWorkspace(workspace) {
|
||||||
workspace.removeChild(this._line2d);
|
workspace.removeChild(this._line2d);
|
||||||
},
|
},
|
||||||
|
|
||||||
getTargetTopic: function () {
|
getTargetTopic() {
|
||||||
return this._targetTopic;
|
return this._targetTopic;
|
||||||
},
|
},
|
||||||
|
|
||||||
getSourceTopic: function () {
|
getSourceTopic() {
|
||||||
return this._sourceTopic;
|
return this._sourceTopic;
|
||||||
},
|
},
|
||||||
|
|
||||||
getLineType: function () {
|
getLineType() {
|
||||||
return this._lineType;
|
return this._lineType;
|
||||||
},
|
},
|
||||||
|
|
||||||
getLine: function () {
|
getLine() {
|
||||||
return this._line2d;
|
return this._line2d;
|
||||||
},
|
},
|
||||||
|
|
||||||
getModel: function () {
|
getModel() {
|
||||||
return this._model;
|
return this._model;
|
||||||
},
|
},
|
||||||
|
|
||||||
setModel: function (model) {
|
setModel(model) {
|
||||||
this._model = model;
|
this._model = model;
|
||||||
},
|
},
|
||||||
|
|
||||||
getType: function () {
|
getType() {
|
||||||
return 'ConnectionLine';
|
return 'ConnectionLine';
|
||||||
},
|
},
|
||||||
|
|
||||||
getId: function () {
|
getId() {
|
||||||
return this._model.getId();
|
return this._model.getId();
|
||||||
},
|
},
|
||||||
|
|
||||||
moveToBack: function () {
|
moveToBack() {
|
||||||
this._line2d.moveToBack();
|
this._line2d.moveToBack();
|
||||||
},
|
},
|
||||||
|
|
||||||
moveToFront: function () {
|
moveToFront() {
|
||||||
this._line2d.moveToFront();
|
this._line2d.moveToFront();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
ConnectionLine.getStrokeColor = function () {
|
ConnectionLine.getStrokeColor = function () {
|
||||||
return '#495879';
|
return '#495879';
|
||||||
};
|
};
|
||||||
|
|
||||||
ConnectionLine.SIMPLE = 0;
|
ConnectionLine.SIMPLE = 0;
|
||||||
|
@ -15,194 +15,193 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
const Core = require('@wismapping/core-js')
|
const Core = require('@wismapping/core-js');
|
||||||
|
|
||||||
const core = Core();
|
const core = Core();
|
||||||
const web2D = require('@wismapping/web2d')
|
const web2D = require('@wismapping/web2d');
|
||||||
|
|
||||||
const web2d = web2D();
|
const web2d = web2D();
|
||||||
|
|
||||||
const Shape = require('./util/Shape').default
|
const Shape = require('./util/Shape').default;
|
||||||
const ActionDispatcher = require('./ActionDispatcher').default;
|
const ActionDispatcher = require('./ActionDispatcher').default;
|
||||||
|
|
||||||
const ControlPoint = new Class({
|
const ControlPoint = new Class({
|
||||||
initialize: function () {
|
initialize() {
|
||||||
var control1 = new web2d.Elipse({
|
const control1 = new web2d.Elipse({
|
||||||
width: 6,
|
width: 6,
|
||||||
height: 6,
|
height: 6,
|
||||||
stroke: '1 solid #6589de',
|
stroke: '1 solid #6589de',
|
||||||
fillColor: 'gray',
|
fillColor: 'gray',
|
||||||
visibility: false
|
visibility: false,
|
||||||
});
|
});
|
||||||
control1.setCursor('pointer');
|
control1.setCursor('pointer');
|
||||||
|
|
||||||
var control2 = new web2d.Elipse({
|
const control2 = new web2d.Elipse({
|
||||||
width: 6,
|
width: 6,
|
||||||
height: 6,
|
height: 6,
|
||||||
stroke: '1 solid #6589de',
|
stroke: '1 solid #6589de',
|
||||||
fillColor: 'gray',
|
fillColor: 'gray',
|
||||||
visibility: false
|
visibility: false,
|
||||||
});
|
});
|
||||||
control2.setCursor('pointer');
|
control2.setCursor('pointer');
|
||||||
|
|
||||||
this._controlPointsController = [control1, control2];
|
this._controlPointsController = [control1, control2];
|
||||||
this._controlLines = [new web2d.Line({strokeColor: "#6589de", strokeWidth: 1, opacity: 0.3}),
|
this._controlLines = [new web2d.Line({ strokeColor: '#6589de', strokeWidth: 1, opacity: 0.3 }),
|
||||||
new web2d.Line({strokeColor: "#6589de", strokeWidth: 1, opacity: 0.3})];
|
new web2d.Line({ strokeColor: '#6589de', strokeWidth: 1, opacity: 0.3 })];
|
||||||
|
|
||||||
this._isBinded = false;
|
this._isBinded = false;
|
||||||
var me = this;
|
const me = this;
|
||||||
this._controlPointsController[0].addEvent('mousedown', function (event) {
|
this._controlPointsController[0].addEvent('mousedown', (event) => {
|
||||||
(me._mouseDown)(event, ControlPoint.FROM, me);
|
(me._mouseDown)(event, ControlPoint.FROM, me);
|
||||||
});
|
});
|
||||||
this._controlPointsController[0].addEvent('click', function (event) {
|
this._controlPointsController[0].addEvent('click', (event) => {
|
||||||
(me._mouseClick)(event);
|
(me._mouseClick)(event);
|
||||||
});
|
});
|
||||||
this._controlPointsController[0].addEvent('dblclick', function (event) {
|
this._controlPointsController[0].addEvent('dblclick', (event) => {
|
||||||
(me._mouseClick)(event);
|
(me._mouseClick)(event);
|
||||||
});
|
});
|
||||||
|
|
||||||
this._controlPointsController[1].addEvent('mousedown', function (event) {
|
this._controlPointsController[1].addEvent('mousedown', (event) => {
|
||||||
(me._mouseDown)(event, ControlPoint.TO, me);
|
(me._mouseDown)(event, ControlPoint.TO, me);
|
||||||
});
|
});
|
||||||
this._controlPointsController[1].addEvent('click', function (event) {
|
this._controlPointsController[1].addEvent('click', (event) => {
|
||||||
(me._mouseClick)(event);
|
(me._mouseClick)(event);
|
||||||
});
|
});
|
||||||
this._controlPointsController[1].addEvent('dblclick', function (event) {
|
this._controlPointsController[1].addEvent('dblclick', (event) => {
|
||||||
(me._mouseClick)(event);
|
(me._mouseClick)(event);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
setLine: function (line) {
|
setLine(line) {
|
||||||
if ($defined(this._line)) {
|
if ($defined(this._line)) {
|
||||||
this._removeLine();
|
this._removeLine();
|
||||||
}
|
|
||||||
this._line = line;
|
|
||||||
this._createControlPoint();
|
|
||||||
this._endPoint = [];
|
|
||||||
this._orignalCtrlPoint = [];
|
|
||||||
this._orignalCtrlPoint[0] = this._controls[0].clone();
|
|
||||||
this._orignalCtrlPoint[1] = this._controls[1].clone();
|
|
||||||
this._endPoint[0] = this._line.getLine().getFrom().clone();
|
|
||||||
this._endPoint[1] = this._line.getLine().getTo().clone();
|
|
||||||
},
|
|
||||||
|
|
||||||
redraw: function () {
|
|
||||||
if ($defined(this._line))
|
|
||||||
this._createControlPoint();
|
|
||||||
},
|
|
||||||
|
|
||||||
_createControlPoint: function () {
|
|
||||||
this._controls = this._line.getLine().getControlPoints();
|
|
||||||
var pos = this._line.getLine().getFrom();
|
|
||||||
this._controlPointsController[0].setPosition(this._controls[ControlPoint.FROM].x + pos.x, this._controls[ControlPoint.FROM].y + pos.y - 3);
|
|
||||||
this._controlLines[0].setFrom(pos.x, pos.y);
|
|
||||||
this._controlLines[0].setTo(this._controls[ControlPoint.FROM].x + pos.x + 3, this._controls[ControlPoint.FROM].y + pos.y);
|
|
||||||
pos = this._line.getLine().getTo();
|
|
||||||
this._controlLines[1].setFrom(pos.x, pos.y);
|
|
||||||
this._controlLines[1].setTo(this._controls[ControlPoint.TO].x + pos.x + 3, this._controls[ControlPoint.TO].y + pos.y);
|
|
||||||
this._controlPointsController[1].setPosition(this._controls[ControlPoint.TO].x + pos.x, this._controls[ControlPoint.TO].y + pos.y - 3);
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
_removeLine: function () {
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
_mouseDown: function (event, point, me) {
|
|
||||||
if (!this._isBinded) {
|
|
||||||
this._isBinded = true;
|
|
||||||
this._mouseMoveFunction = function (event) {
|
|
||||||
(me._mouseMoveEvent)(event, point, me);
|
|
||||||
};
|
|
||||||
|
|
||||||
this._workspace.getScreenManager().addEvent('mousemove', this._mouseMoveFunction);
|
|
||||||
this._mouseUpFunction = function (event) {
|
|
||||||
(me._mouseUp)(event, point, me);
|
|
||||||
};
|
|
||||||
this._workspace.getScreenManager().addEvent('mouseup', this._mouseUpFunction);
|
|
||||||
}
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
_mouseMoveEvent: function (event, point) {
|
|
||||||
var screen = this._workspace.getScreenManager();
|
|
||||||
var pos = screen.getWorkspaceMousePosition(event);
|
|
||||||
|
|
||||||
var cords;
|
|
||||||
if (point == 0) {
|
|
||||||
cords = Shape.calculateRelationShipPointCoordinates(this._line.getSourceTopic(), pos);
|
|
||||||
this._line.setFrom(cords.x, cords.y);
|
|
||||||
this._line.setSrcControlPoint(new core.Point(pos.x - cords.x, pos.y - cords.y));
|
|
||||||
} else {
|
|
||||||
cords = Shape.calculateRelationShipPointCoordinates(this._line.getTargetTopic(), pos);
|
|
||||||
this._line.setTo(cords.x, cords.y);
|
|
||||||
this._line.setDestControlPoint(new core.Point(pos.x - cords.x, pos.y - cords.y));
|
|
||||||
}
|
|
||||||
|
|
||||||
this._controls[point].x = (pos.x - cords.x);
|
|
||||||
this._controls[point].y = (pos.y - cords.y);
|
|
||||||
this._controlPointsController[point].setPosition(pos.x - 5, pos.y - 3);
|
|
||||||
this._controlLines[point].setFrom(cords.x, cords.y);
|
|
||||||
this._controlLines[point].setTo(pos.x - 2, pos.y);
|
|
||||||
this._line.getLine().updateLine(point);
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
_mouseUp: function (event, point) {
|
|
||||||
this._workspace.getScreenManager().removeEvent('mousemove', this._mouseMoveFunction);
|
|
||||||
this._workspace.getScreenManager().removeEvent('mouseup', this._mouseUpFunction);
|
|
||||||
|
|
||||||
var actionDispatcher = ActionDispatcher.getInstance();
|
|
||||||
actionDispatcher.moveControlPoint(this, point);
|
|
||||||
this._isBinded = false;
|
|
||||||
},
|
|
||||||
|
|
||||||
_mouseClick: function (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
setVisibility: function (visible) {
|
|
||||||
if (visible) {
|
|
||||||
this._controlLines[0].moveToFront();
|
|
||||||
this._controlLines[1].moveToFront();
|
|
||||||
this._controlPointsController[0].moveToFront();
|
|
||||||
this._controlPointsController[1].moveToFront();
|
|
||||||
}
|
|
||||||
this._controlPointsController[0].setVisibility(visible);
|
|
||||||
this._controlPointsController[1].setVisibility(visible);
|
|
||||||
this._controlLines[0].setVisibility(visible);
|
|
||||||
this._controlLines[1].setVisibility(visible);
|
|
||||||
},
|
|
||||||
|
|
||||||
addToWorkspace: function (workspace) {
|
|
||||||
this._workspace = workspace;
|
|
||||||
workspace.append(this._controlPointsController[0]);
|
|
||||||
workspace.append(this._controlPointsController[1]);
|
|
||||||
workspace.append(this._controlLines[0]);
|
|
||||||
workspace.append(this._controlLines[1]);
|
|
||||||
},
|
|
||||||
|
|
||||||
removeFromWorkspace: function (workspace) {
|
|
||||||
this._workspace = null;
|
|
||||||
workspace.removeChild(this._controlPointsController[0]);
|
|
||||||
workspace.removeChild(this._controlPointsController[1]);
|
|
||||||
workspace.removeChild(this._controlLines[0]);
|
|
||||||
workspace.removeChild(this._controlLines[1]);
|
|
||||||
},
|
|
||||||
|
|
||||||
getControlPoint: function (index) {
|
|
||||||
return this._controls[index];
|
|
||||||
},
|
|
||||||
|
|
||||||
getOriginalEndPoint: function (index) {
|
|
||||||
return this._endPoint[index];
|
|
||||||
},
|
|
||||||
|
|
||||||
getOriginalCtrlPoint: function (index) {
|
|
||||||
return this._orignalCtrlPoint[index];
|
|
||||||
}
|
}
|
||||||
|
this._line = line;
|
||||||
|
this._createControlPoint();
|
||||||
|
this._endPoint = [];
|
||||||
|
this._orignalCtrlPoint = [];
|
||||||
|
this._orignalCtrlPoint[0] = this._controls[0].clone();
|
||||||
|
this._orignalCtrlPoint[1] = this._controls[1].clone();
|
||||||
|
this._endPoint[0] = this._line.getLine().getFrom().clone();
|
||||||
|
this._endPoint[1] = this._line.getLine().getTo().clone();
|
||||||
|
},
|
||||||
|
|
||||||
|
redraw() {
|
||||||
|
if ($defined(this._line)) this._createControlPoint();
|
||||||
|
},
|
||||||
|
|
||||||
|
_createControlPoint() {
|
||||||
|
this._controls = this._line.getLine().getControlPoints();
|
||||||
|
let pos = this._line.getLine().getFrom();
|
||||||
|
this._controlPointsController[0].setPosition(this._controls[ControlPoint.FROM].x + pos.x, this._controls[ControlPoint.FROM].y + pos.y - 3);
|
||||||
|
this._controlLines[0].setFrom(pos.x, pos.y);
|
||||||
|
this._controlLines[0].setTo(this._controls[ControlPoint.FROM].x + pos.x + 3, this._controls[ControlPoint.FROM].y + pos.y);
|
||||||
|
pos = this._line.getLine().getTo();
|
||||||
|
this._controlLines[1].setFrom(pos.x, pos.y);
|
||||||
|
this._controlLines[1].setTo(this._controls[ControlPoint.TO].x + pos.x + 3, this._controls[ControlPoint.TO].y + pos.y);
|
||||||
|
this._controlPointsController[1].setPosition(this._controls[ControlPoint.TO].x + pos.x, this._controls[ControlPoint.TO].y + pos.y - 3);
|
||||||
|
},
|
||||||
|
|
||||||
|
_removeLine() {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
_mouseDown(event, point, me) {
|
||||||
|
if (!this._isBinded) {
|
||||||
|
this._isBinded = true;
|
||||||
|
this._mouseMoveFunction = function (event) {
|
||||||
|
(me._mouseMoveEvent)(event, point, me);
|
||||||
|
};
|
||||||
|
|
||||||
|
this._workspace.getScreenManager().addEvent('mousemove', this._mouseMoveFunction);
|
||||||
|
this._mouseUpFunction = function (event) {
|
||||||
|
(me._mouseUp)(event, point, me);
|
||||||
|
};
|
||||||
|
this._workspace.getScreenManager().addEvent('mouseup', this._mouseUpFunction);
|
||||||
|
}
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_mouseMoveEvent(event, point) {
|
||||||
|
const screen = this._workspace.getScreenManager();
|
||||||
|
const pos = screen.getWorkspaceMousePosition(event);
|
||||||
|
|
||||||
|
let cords;
|
||||||
|
if (point == 0) {
|
||||||
|
cords = Shape.calculateRelationShipPointCoordinates(this._line.getSourceTopic(), pos);
|
||||||
|
this._line.setFrom(cords.x, cords.y);
|
||||||
|
this._line.setSrcControlPoint(new core.Point(pos.x - cords.x, pos.y - cords.y));
|
||||||
|
} else {
|
||||||
|
cords = Shape.calculateRelationShipPointCoordinates(this._line.getTargetTopic(), pos);
|
||||||
|
this._line.setTo(cords.x, cords.y);
|
||||||
|
this._line.setDestControlPoint(new core.Point(pos.x - cords.x, pos.y - cords.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
this._controls[point].x = (pos.x - cords.x);
|
||||||
|
this._controls[point].y = (pos.y - cords.y);
|
||||||
|
this._controlPointsController[point].setPosition(pos.x - 5, pos.y - 3);
|
||||||
|
this._controlLines[point].setFrom(cords.x, cords.y);
|
||||||
|
this._controlLines[point].setTo(pos.x - 2, pos.y);
|
||||||
|
this._line.getLine().updateLine(point);
|
||||||
|
},
|
||||||
|
|
||||||
|
_mouseUp(event, point) {
|
||||||
|
this._workspace.getScreenManager().removeEvent('mousemove', this._mouseMoveFunction);
|
||||||
|
this._workspace.getScreenManager().removeEvent('mouseup', this._mouseUpFunction);
|
||||||
|
|
||||||
|
const actionDispatcher = ActionDispatcher.getInstance();
|
||||||
|
actionDispatcher.moveControlPoint(this, point);
|
||||||
|
this._isBinded = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_mouseClick(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
setVisibility(visible) {
|
||||||
|
if (visible) {
|
||||||
|
this._controlLines[0].moveToFront();
|
||||||
|
this._controlLines[1].moveToFront();
|
||||||
|
this._controlPointsController[0].moveToFront();
|
||||||
|
this._controlPointsController[1].moveToFront();
|
||||||
|
}
|
||||||
|
this._controlPointsController[0].setVisibility(visible);
|
||||||
|
this._controlPointsController[1].setVisibility(visible);
|
||||||
|
this._controlLines[0].setVisibility(visible);
|
||||||
|
this._controlLines[1].setVisibility(visible);
|
||||||
|
},
|
||||||
|
|
||||||
|
addToWorkspace(workspace) {
|
||||||
|
this._workspace = workspace;
|
||||||
|
workspace.append(this._controlPointsController[0]);
|
||||||
|
workspace.append(this._controlPointsController[1]);
|
||||||
|
workspace.append(this._controlLines[0]);
|
||||||
|
workspace.append(this._controlLines[1]);
|
||||||
|
},
|
||||||
|
|
||||||
|
removeFromWorkspace(workspace) {
|
||||||
|
this._workspace = null;
|
||||||
|
workspace.removeChild(this._controlPointsController[0]);
|
||||||
|
workspace.removeChild(this._controlPointsController[1]);
|
||||||
|
workspace.removeChild(this._controlLines[0]);
|
||||||
|
workspace.removeChild(this._controlLines[1]);
|
||||||
|
},
|
||||||
|
|
||||||
|
getControlPoint(index) {
|
||||||
|
return this._controls[index];
|
||||||
|
},
|
||||||
|
|
||||||
|
getOriginalEndPoint(index) {
|
||||||
|
return this._endPoint[index];
|
||||||
|
},
|
||||||
|
|
||||||
|
getOriginalCtrlPoint(index) {
|
||||||
|
return this._orignalCtrlPoint[index];
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
ControlPoint.FROM = 0;
|
ControlPoint.FROM = 0;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -19,40 +19,38 @@ const DesignerUndoManager = require('./DesignerUndoManager').default;
|
|||||||
const EventBus = require('./layout/EventBus').default;
|
const EventBus = require('./layout/EventBus').default;
|
||||||
|
|
||||||
const DesignerActionRunner = new Class({
|
const DesignerActionRunner = new Class({
|
||||||
initialize: function (commandContext, notifier) {
|
initialize(commandContext, notifier) {
|
||||||
$assert(commandContext, "commandContext can not be null");
|
$assert(commandContext, 'commandContext can not be null');
|
||||||
|
|
||||||
this._undoManager = new DesignerUndoManager();
|
this._undoManager = new DesignerUndoManager();
|
||||||
this._context = commandContext;
|
this._context = commandContext;
|
||||||
this._notifier = notifier;
|
this._notifier = notifier;
|
||||||
},
|
},
|
||||||
|
|
||||||
execute: function (command) {
|
execute(command) {
|
||||||
$assert(command, "command can not be null");
|
$assert(command, 'command can not be null');
|
||||||
command.execute(this._context);
|
command.execute(this._context);
|
||||||
this._undoManager.enqueue(command);
|
this._undoManager.enqueue(command);
|
||||||
this.fireChangeEvent();
|
this.fireChangeEvent();
|
||||||
EventBus.instance.fireEvent(EventBus.events.DoLayout);
|
EventBus.instance.fireEvent(EventBus.events.DoLayout);
|
||||||
|
},
|
||||||
|
|
||||||
},
|
undo() {
|
||||||
|
this._undoManager.execUndo(this._context);
|
||||||
|
this.fireChangeEvent();
|
||||||
|
EventBus.instance.fireEvent(EventBus.events.DoLayout);
|
||||||
|
},
|
||||||
|
|
||||||
undo: function () {
|
redo() {
|
||||||
this._undoManager.execUndo(this._context);
|
this._undoManager.execRedo(this._context);
|
||||||
this.fireChangeEvent();
|
this.fireChangeEvent();
|
||||||
EventBus.instance.fireEvent(EventBus.events.DoLayout);
|
EventBus.instance.fireEvent(EventBus.events.DoLayout);
|
||||||
},
|
},
|
||||||
|
|
||||||
redo: function () {
|
fireChangeEvent() {
|
||||||
this._undoManager.execRedo(this._context);
|
const event = this._undoManager.buildEvent();
|
||||||
this.fireChangeEvent();
|
this._notifier.fireEvent('modelUpdate', event);
|
||||||
EventBus.instance.fireEvent(EventBus.events.DoLayout);
|
},
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
fireChangeEvent: function () {
|
|
||||||
var event = this._undoManager.buildEvent();
|
|
||||||
this._notifier.fireEvent("modelUpdate", event);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default DesignerActionRunner;
|
export default DesignerActionRunner;
|
||||||
|
@ -18,383 +18,416 @@
|
|||||||
const Keyboard = require('./Keyboard').default;
|
const Keyboard = require('./Keyboard').default;
|
||||||
|
|
||||||
const DesignerKeyboard = new Class({
|
const DesignerKeyboard = new Class({
|
||||||
Extends: Keyboard,
|
Extends: Keyboard,
|
||||||
Static:{
|
Static: {
|
||||||
register:function (designer) {
|
register(designer) {
|
||||||
this._instance = new DesignerKeyboard(designer);
|
this._instance = new DesignerKeyboard(designer);
|
||||||
},
|
},
|
||||||
|
|
||||||
getInstance:function () {
|
getInstance() {
|
||||||
return this._instance;
|
return this._instance;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
initialize(designer) {
|
||||||
|
$assert(designer, 'designer can not be null');
|
||||||
|
this._registerEvents(designer);
|
||||||
|
},
|
||||||
|
|
||||||
|
_registerEvents(designer) {
|
||||||
|
// Try with the keyboard ..
|
||||||
|
const model = designer.getModel();
|
||||||
|
this.addShortcut(
|
||||||
|
['backspace'], (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
designer.deleteSelectedEntities();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
this.addShortcut(
|
||||||
|
['space'], () => {
|
||||||
|
designer.shrinkSelectedBranch();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
this.addShortcut(
|
||||||
|
['f2'], (event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
event.preventDefault();
|
||||||
|
const node = model.selectedTopic();
|
||||||
|
if (node) {
|
||||||
|
node.showTextEditor();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
);
|
||||||
|
this.addShortcut(
|
||||||
|
['del'], (event) => {
|
||||||
|
designer.deleteSelectedEntities();
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
this.addShortcut(
|
||||||
|
['enter'], () => {
|
||||||
|
designer.createSiblingForSelectedNode();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
this.addShortcut(
|
||||||
|
['insert'], (event) => {
|
||||||
|
designer.createChildForSelectedNode();
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
this.addShortcut(
|
||||||
|
['tab'], (event) => {
|
||||||
|
designer.createChildForSelectedNode();
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
this.addShortcut(
|
||||||
|
['meta+enter'], (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
designer.createChildForSelectedNode();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
this.addShortcut(
|
||||||
|
['ctrl+z', 'meta+z'], (event) => {
|
||||||
|
event.preventDefault(event);
|
||||||
|
event.stopPropagation();
|
||||||
|
designer.undo();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
this.addShortcut(
|
||||||
|
['ctrl+c', 'meta+c'], (event) => {
|
||||||
|
event.preventDefault(event);
|
||||||
|
event.stopPropagation();
|
||||||
|
designer.copyToClipboard();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
this.addShortcut(
|
||||||
|
['ctrl+v', 'meta+v'], (event) => {
|
||||||
|
event.preventDefault(event);
|
||||||
|
event.stopPropagation();
|
||||||
|
designer.pasteClipboard();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
this.addShortcut(
|
||||||
|
['ctrl+shift+z', 'meta+shift+z', 'ctrl+y', 'meta+y'], (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
designer.redo();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
this.addShortcut(
|
||||||
|
['ctrl+a', 'meta+a'], (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
designer.selectAll();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
this.addShortcut(
|
||||||
|
['ctrl+b', 'meta+b'], (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
initialize:function (designer) {
|
designer.changeFontWeight();
|
||||||
$assert(designer, "designer can not be null");
|
},
|
||||||
this._registerEvents(designer);
|
);
|
||||||
},
|
this.addShortcut(
|
||||||
|
['ctrl+s', 'meta+s'], (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
$(document).find('#save').trigger('click');
|
||||||
|
},
|
||||||
|
);
|
||||||
|
this.addShortcut(
|
||||||
|
['ctrl+i', 'meta+i'], (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
_registerEvents:function (designer) {
|
designer.changeFontStyle();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
this.addShortcut(
|
||||||
|
['ctrl+shift+a', 'meta+shift+a'], (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
// Try with the keyboard ..
|
|
||||||
var model = designer.getModel();
|
|
||||||
this.addShortcut(
|
|
||||||
['backspace'], function (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
designer.deleteSelectedEntities();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.addShortcut(
|
|
||||||
['space'], function() {
|
|
||||||
designer.shrinkSelectedBranch();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.addShortcut(
|
|
||||||
['f2'],function(event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
event.preventDefault();
|
|
||||||
var node = model.selectedTopic();
|
|
||||||
if (node) {
|
|
||||||
node.showTextEditor();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.addShortcut(
|
|
||||||
['del'], function(event) {
|
|
||||||
designer.deleteSelectedEntities();
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.addShortcut(
|
|
||||||
['enter'], function() {
|
|
||||||
designer.createSiblingForSelectedNode();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.addShortcut(
|
|
||||||
['insert'], function(event) {
|
|
||||||
designer.createChildForSelectedNode();
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.addShortcut(
|
|
||||||
['tab'], function(event) {
|
|
||||||
designer.createChildForSelectedNode();
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.addShortcut(
|
|
||||||
['meta+enter'], function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
designer.createChildForSelectedNode();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.addShortcut(
|
|
||||||
['ctrl+z', 'meta+z'], function(event) {
|
|
||||||
event.preventDefault(event);
|
|
||||||
event.stopPropagation();
|
|
||||||
designer.undo();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.addShortcut(
|
|
||||||
['ctrl+c', 'meta+c'], function (event) {
|
|
||||||
event.preventDefault(event);
|
|
||||||
event.stopPropagation();
|
|
||||||
designer.copyToClipboard();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.addShortcut(
|
|
||||||
['ctrl+v', 'meta+v'], function (event) {
|
|
||||||
event.preventDefault(event);
|
|
||||||
event.stopPropagation();
|
|
||||||
designer.pasteClipboard();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.addShortcut(
|
|
||||||
['ctrl+shift+z', 'meta+shift+z', 'ctrl+y', 'meta+y'], function (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
designer.redo();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.addShortcut(
|
|
||||||
['ctrl+a', 'meta+a'], function (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
designer.selectAll();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.addShortcut(
|
|
||||||
['ctrl+b', 'meta+b'], function (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
|
|
||||||
designer.changeFontWeight();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.addShortcut(
|
|
||||||
['ctrl+s', 'meta+s'], function (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
$(document).find('#save').trigger('click');
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.addShortcut(
|
|
||||||
['ctrl+i', 'meta+i'], function (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
|
|
||||||
designer.changeFontStyle();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.addShortcut(
|
|
||||||
['ctrl+shift+a', 'meta+shift+a'], function (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
|
|
||||||
designer.deselectAll();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.addShortcut(
|
|
||||||
['meta+=', 'ctrl+='], function (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
|
|
||||||
designer.zoomIn();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.addShortcut(
|
|
||||||
['meta+-', 'ctrl+-'], function (event) {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
|
|
||||||
designer.zoomOut();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
var me = this;
|
|
||||||
this.addShortcut(
|
|
||||||
'right', function (event) {
|
|
||||||
var node = model.selectedTopic();
|
|
||||||
if (node) {
|
|
||||||
if (node.isCentralTopic()) {
|
|
||||||
me._goToSideChild(designer, node, 'RIGHT');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (node.getPosition().x < 0) {
|
|
||||||
me._goToParent(designer, node);
|
|
||||||
}
|
|
||||||
else if (!node.areChildrenShrunken()) {
|
|
||||||
me._goToChild(designer, node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var centralTopic = model.getCentralTopic();
|
|
||||||
me._goToNode(designer, centralTopic);
|
|
||||||
}
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.addShortcut(
|
|
||||||
'left', function (event) {
|
|
||||||
var node = model.selectedTopic();
|
|
||||||
if (node) {
|
|
||||||
if (node.isCentralTopic()) {
|
|
||||||
me._goToSideChild(designer, node, 'LEFT');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (node.getPosition().x > 0) {
|
|
||||||
me._goToParent(designer, node);
|
|
||||||
}
|
|
||||||
else if (!node.areChildrenShrunken()) {
|
|
||||||
me._goToChild(designer, node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var centralTopic = model.getCentralTopic();
|
|
||||||
me._goToNode(designer, centralTopic);
|
|
||||||
}
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.addShortcut(
|
|
||||||
'up', function (event) {
|
|
||||||
var node = model.selectedTopic();
|
|
||||||
if (node) {
|
|
||||||
if (!node.isCentralTopic()) {
|
|
||||||
me._goToBrother(designer, node, 'UP');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var centralTopic = model.getCentralTopic();
|
|
||||||
me._goToNode(designer, centralTopic);
|
|
||||||
}
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
this.addShortcut(
|
|
||||||
'down', function (event) {
|
|
||||||
var node = model.selectedTopic();
|
|
||||||
if (node) {
|
|
||||||
if (!node.isCentralTopic()) {
|
|
||||||
me._goToBrother(designer, node, 'DOWN');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var centralTopic = model.getCentralTopic();
|
|
||||||
me._goToNode(designer, centralTopic);
|
|
||||||
}
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
var excludes = ['esc', 'escape', 'f1', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10', 'f11', 'f12'];
|
|
||||||
|
|
||||||
$(document).on('keypress', function (event) {
|
|
||||||
var keyCode;
|
|
||||||
// Firefox doesn't skip special keys for keypress event...
|
|
||||||
if (event.key && excludes.contains(event.key.toLowerCase())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Sometimes Firefox doesn't contain keyCode value
|
|
||||||
if (event.key && event.keyCode == 0) {
|
|
||||||
keyCode = event.charCode;
|
|
||||||
} else {
|
|
||||||
keyCode = event.keyCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
var specialKey = jQuery.hotkeys.specialKeys[keyCode];
|
|
||||||
if (["enter", "capslock"].indexOf(specialKey) == -1 && !jQuery.hotkeys.shiftNums[keyCode]) {
|
|
||||||
var nodes = designer.getModel().filterSelectedTopics();
|
|
||||||
if (nodes.length > 0) {
|
|
||||||
|
|
||||||
// If a modifier is press, the key selected must be ignored.
|
|
||||||
var pressKey = String.fromCharCode(keyCode);
|
|
||||||
if (event.ctrlKey || event.altKey || event.metaKey) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
nodes[0].showTextEditor(pressKey);
|
|
||||||
event.stopPropagation();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
_goToBrother:function (designer, node, direction) {
|
|
||||||
var parent = node.getParent();
|
|
||||||
if (parent) {
|
|
||||||
var brothers = parent.getChildren();
|
|
||||||
|
|
||||||
var target = node;
|
|
||||||
var y = node.getPosition().y;
|
|
||||||
var x = node.getPosition().x;
|
|
||||||
var dist = null;
|
|
||||||
for (var i = 0; i < brothers.length; i++) {
|
|
||||||
var sameSide = (x * brothers[i].getPosition().x) >= 0;
|
|
||||||
if (brothers[i] != node && sameSide) {
|
|
||||||
var brother = brothers[i];
|
|
||||||
var brotherY = brother.getPosition().y;
|
|
||||||
if (direction == "DOWN" && brotherY > y) {
|
|
||||||
var distancia = y - brotherY;
|
|
||||||
if (distancia < 0) {
|
|
||||||
distancia = distancia * (-1);
|
|
||||||
}
|
|
||||||
if (dist == null || dist > distancia) {
|
|
||||||
dist = distancia;
|
|
||||||
target = brothers[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (direction == "UP" && brotherY < y) {
|
|
||||||
var distance = y - brotherY;
|
|
||||||
if (distance < 0) {
|
|
||||||
distance = distance * (-1);
|
|
||||||
}
|
|
||||||
if (dist == null || dist > distance) {
|
|
||||||
dist = distance;
|
|
||||||
target = brothers[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this._goToNode(designer, target);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
_goToSideChild:function (designer, node, side) {
|
|
||||||
var children = node.getChildren();
|
|
||||||
if (children.length > 0) {
|
|
||||||
var target = children[0];
|
|
||||||
var top = null;
|
|
||||||
for (var i = 0; i < children.length; i++) {
|
|
||||||
var child = children[i];
|
|
||||||
var childY = child.getPosition().y;
|
|
||||||
if (side == 'LEFT' && child.getPosition().x < 0) {
|
|
||||||
if (top == null || childY < top) {
|
|
||||||
target = child;
|
|
||||||
top = childY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (side == 'RIGHT' && child.getPosition().x > 0) {
|
|
||||||
if (top == null || childY < top) {
|
|
||||||
target = child;
|
|
||||||
top = childY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this._goToNode(designer, target);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_goToParent:function (designer, node) {
|
|
||||||
var parent = node.getParent();
|
|
||||||
if (parent) {
|
|
||||||
this._goToNode(designer, parent);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_goToChild:function (designer, node) {
|
|
||||||
var children = node.getChildren();
|
|
||||||
if (children.length > 0) {
|
|
||||||
var target = children[0];
|
|
||||||
var top = target.getPosition().y;
|
|
||||||
for (var i = 0; i < children.length; i++) {
|
|
||||||
var child = children[i];
|
|
||||||
if (child.getPosition().y < top) {
|
|
||||||
top = child.getPosition().y;
|
|
||||||
target = child;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this._goToNode(designer, target);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_goToNode:function (designer, node) {
|
|
||||||
// First deselect all the nodes ...
|
|
||||||
designer.deselectAll();
|
designer.deselectAll();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
this.addShortcut(
|
||||||
|
['meta+=', 'ctrl+='], (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
// Give focus to the selected node....
|
designer.zoomIn();
|
||||||
node.setOnFocus(true);
|
},
|
||||||
|
);
|
||||||
|
this.addShortcut(
|
||||||
|
['meta+-', 'ctrl+-'], (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
designer.zoomOut();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
const me = this;
|
||||||
|
this.addShortcut(
|
||||||
|
'right', (event) => {
|
||||||
|
const node = model.selectedTopic();
|
||||||
|
if (node) {
|
||||||
|
if (node.isCentralTopic()) {
|
||||||
|
me._goToSideChild(designer, node, 'RIGHT');
|
||||||
|
} else if (node.getPosition().x < 0) {
|
||||||
|
me._goToParent(designer, node);
|
||||||
|
} else if (!node.areChildrenShrunken()) {
|
||||||
|
me._goToChild(designer, node);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const centralTopic = model.getCentralTopic();
|
||||||
|
me._goToNode(designer, centralTopic);
|
||||||
|
}
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
this.addShortcut(
|
||||||
|
'left', (event) => {
|
||||||
|
const node = model.selectedTopic();
|
||||||
|
if (node) {
|
||||||
|
if (node.isCentralTopic()) {
|
||||||
|
me._goToSideChild(designer, node, 'LEFT');
|
||||||
|
} else if (node.getPosition().x > 0) {
|
||||||
|
me._goToParent(designer, node);
|
||||||
|
} else if (!node.areChildrenShrunken()) {
|
||||||
|
me._goToChild(designer, node);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const centralTopic = model.getCentralTopic();
|
||||||
|
me._goToNode(designer, centralTopic);
|
||||||
|
}
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
this.addShortcut(
|
||||||
|
'up', (event) => {
|
||||||
|
const node = model.selectedTopic();
|
||||||
|
if (node) {
|
||||||
|
if (!node.isCentralTopic()) {
|
||||||
|
me._goToBrother(designer, node, 'UP');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const centralTopic = model.getCentralTopic();
|
||||||
|
me._goToNode(designer, centralTopic);
|
||||||
|
}
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
this.addShortcut(
|
||||||
|
'down', (event) => {
|
||||||
|
const node = model.selectedTopic();
|
||||||
|
if (node) {
|
||||||
|
if (!node.isCentralTopic()) {
|
||||||
|
me._goToBrother(designer, node, 'DOWN');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const centralTopic = model.getCentralTopic();
|
||||||
|
me._goToNode(designer, centralTopic);
|
||||||
|
}
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
const excludes = ['esc', 'escape', 'f1', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10', 'f11', 'f12'];
|
||||||
|
|
||||||
|
$(document).on('keypress', (event) => {
|
||||||
|
let keyCode;
|
||||||
|
// Firefox doesn't skip special keys for keypress event...
|
||||||
|
if (event.key && excludes.contains(event.key.toLowerCase())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Sometimes Firefox doesn't contain keyCode value
|
||||||
|
if (event.key && event.keyCode == 0) {
|
||||||
|
keyCode = event.charCode;
|
||||||
|
} else {
|
||||||
|
keyCode = event.keyCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
const specialKey = jQuery.hotkeys.specialKeys[keyCode];
|
||||||
|
if (['enter', 'capslock'].indexOf(specialKey) == -1 && !jQuery.hotkeys.shiftNums[keyCode]) {
|
||||||
|
const nodes = designer.getModel().filterSelectedTopics();
|
||||||
|
if (nodes.length > 0) {
|
||||||
|
// If a modifier is press, the key selected must be ignored.
|
||||||
|
const pressKey = String.fromCharCode(keyCode);
|
||||||
|
if (event.ctrlKey || event.altKey || event.metaKey) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nodes[0].showTextEditor(pressKey);
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_goToBrother(designer, node, direction) {
|
||||||
|
const parent = node.getParent();
|
||||||
|
if (parent) {
|
||||||
|
const brothers = parent.getChildren();
|
||||||
|
|
||||||
|
let target = node;
|
||||||
|
const { y } = node.getPosition();
|
||||||
|
const { x } = node.getPosition();
|
||||||
|
let dist = null;
|
||||||
|
for (let i = 0; i < brothers.length; i++) {
|
||||||
|
const sameSide = (x * brothers[i].getPosition().x) >= 0;
|
||||||
|
if (brothers[i] != node && sameSide) {
|
||||||
|
const brother = brothers[i];
|
||||||
|
const brotherY = brother.getPosition().y;
|
||||||
|
if (direction == 'DOWN' && brotherY > y) {
|
||||||
|
let distancia = y - brotherY;
|
||||||
|
if (distancia < 0) {
|
||||||
|
distancia *= (-1);
|
||||||
|
}
|
||||||
|
if (dist == null || dist > distancia) {
|
||||||
|
dist = distancia;
|
||||||
|
target = brothers[i];
|
||||||
|
}
|
||||||
|
} else if (direction == 'UP' && brotherY < y) {
|
||||||
|
let distance = y - brotherY;
|
||||||
|
if (distance < 0) {
|
||||||
|
distance *= (-1);
|
||||||
|
}
|
||||||
|
if (dist == null || dist > distance) {
|
||||||
|
dist = distance;
|
||||||
|
target = brothers[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this._goToNode(designer, target);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_goToSideChild(designer, node, side) {
|
||||||
|
const children = node.getChildren();
|
||||||
|
if (children.length > 0) {
|
||||||
|
let target = children[0];
|
||||||
|
let top = null;
|
||||||
|
for (let i = 0; i < children.length; i++) {
|
||||||
|
const child = children[i];
|
||||||
|
const childY = child.getPosition().y;
|
||||||
|
if (side == 'LEFT' && child.getPosition().x < 0) {
|
||||||
|
if (top == null || childY < top) {
|
||||||
|
target = child;
|
||||||
|
top = childY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (side == 'RIGHT' && child.getPosition().x > 0) {
|
||||||
|
if (top == null || childY < top) {
|
||||||
|
target = child;
|
||||||
|
top = childY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this._goToNode(designer, target);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_goToParent(designer, node) {
|
||||||
|
const parent = node.getParent();
|
||||||
|
if (parent) {
|
||||||
|
this._goToNode(designer, parent);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_goToChild(designer, node) {
|
||||||
|
const children = node.getChildren();
|
||||||
|
if (children.length > 0) {
|
||||||
|
let target = children[0];
|
||||||
|
let top = target.getPosition().y;
|
||||||
|
for (let i = 0; i < children.length; i++) {
|
||||||
|
const child = children[i];
|
||||||
|
if (child.getPosition().y < top) {
|
||||||
|
top = child.getPosition().y;
|
||||||
|
target = child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this._goToNode(designer, target);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_goToNode(designer, node) {
|
||||||
|
// First deselect all the nodes ...
|
||||||
|
designer.deselectAll();
|
||||||
|
|
||||||
|
// Give focus to the selected node....
|
||||||
|
node.setOnFocus(true);
|
||||||
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
DesignerKeyboard.specialKeys = {
|
DesignerKeyboard.specialKeys = {
|
||||||
8: "backspace", 9: "tab", 10: "return", 13: "enter", 16: "shift", 17: "ctrl", 18: "alt", 19: "pause",
|
8: 'backspace',
|
||||||
20: "capslock", 27: "esc", 32: "space", 33: "pageup", 34: "pagedown", 35: "end", 36: "home",
|
9: 'tab',
|
||||||
37: "left", 38: "up", 39: "right", 40: "down", 45: "insert", 46: "del",
|
10: 'return',
|
||||||
96: "0", 97: "1", 98: "2", 99: "3", 100: "4", 101: "5", 102: "6", 103: "7",
|
13: 'enter',
|
||||||
104: "8", 105: "9", 106: "*", 107: "+", 109: "-", 110: ".", 111 : "/",
|
16: 'shift',
|
||||||
112: "f1", 113: "f2", 114: "f3", 115: "f4", 116: "f5", 117: "f6", 118: "f7", 119: "f8",
|
17: 'ctrl',
|
||||||
120: "f9", 121: "f10", 122: "f11", 123: "f12", 144: "numlock", 145: "scroll", 186: ";", 191: "/",
|
18: 'alt',
|
||||||
220: "\\", 222: "'", 224: "meta"
|
19: 'pause',
|
||||||
|
20: 'capslock',
|
||||||
|
27: 'esc',
|
||||||
|
32: 'space',
|
||||||
|
33: 'pageup',
|
||||||
|
34: 'pagedown',
|
||||||
|
35: 'end',
|
||||||
|
36: 'home',
|
||||||
|
37: 'left',
|
||||||
|
38: 'up',
|
||||||
|
39: 'right',
|
||||||
|
40: 'down',
|
||||||
|
45: 'insert',
|
||||||
|
46: 'del',
|
||||||
|
96: '0',
|
||||||
|
97: '1',
|
||||||
|
98: '2',
|
||||||
|
99: '3',
|
||||||
|
100: '4',
|
||||||
|
101: '5',
|
||||||
|
102: '6',
|
||||||
|
103: '7',
|
||||||
|
104: '8',
|
||||||
|
105: '9',
|
||||||
|
106: '*',
|
||||||
|
107: '+',
|
||||||
|
109: '-',
|
||||||
|
110: '.',
|
||||||
|
111: '/',
|
||||||
|
112: 'f1',
|
||||||
|
113: 'f2',
|
||||||
|
114: 'f3',
|
||||||
|
115: 'f4',
|
||||||
|
116: 'f5',
|
||||||
|
117: 'f6',
|
||||||
|
118: 'f7',
|
||||||
|
119: 'f8',
|
||||||
|
120: 'f9',
|
||||||
|
121: 'f10',
|
||||||
|
122: 'f11',
|
||||||
|
123: 'f12',
|
||||||
|
144: 'numlock',
|
||||||
|
145: 'scroll',
|
||||||
|
186: ';',
|
||||||
|
191: '/',
|
||||||
|
220: '\\',
|
||||||
|
222: "'",
|
||||||
|
224: 'meta',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DesignerKeyboard;
|
export default DesignerKeyboard;
|
||||||
|
@ -18,8 +18,8 @@
|
|||||||
const Events = require('./Events').default;
|
const Events = require('./Events').default;
|
||||||
|
|
||||||
const DesignerModel = new Class(/** @lends DesignerModel */{
|
const DesignerModel = new Class(/** @lends DesignerModel */{
|
||||||
Implements:[Events],
|
Implements: [Events],
|
||||||
/**
|
/**
|
||||||
* @implements {mindplot.Events}
|
* @implements {mindplot.Events}
|
||||||
* @constructs
|
* @constructs
|
||||||
* @param {{readOnly: Boolean, zoom: Number, saveOnLoad: Boolean, size: {width: Number,
|
* @param {{readOnly: Boolean, zoom: Number, saveOnLoad: Boolean, size: {width: Number,
|
||||||
@ -29,163 +29,161 @@ const DesignerModel = new Class(/** @lends DesignerModel */{
|
|||||||
* @see {@link ConfigParameters.md}
|
* @see {@link ConfigParameters.md}
|
||||||
* @see {@link editor.html}
|
* @see {@link editor.html}
|
||||||
*/
|
*/
|
||||||
initialize:function (options) {
|
initialize(options) {
|
||||||
this._zoom = options.zoom;
|
this._zoom = options.zoom;
|
||||||
this._topics = [];
|
this._topics = [];
|
||||||
this._relationships = [];
|
this._relationships = [];
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @return {Number} zoom between 0.3 (largest text) and 1.9 */
|
/** @return {Number} zoom between 0.3 (largest text) and 1.9 */
|
||||||
getZoom:function () {
|
getZoom() {
|
||||||
return this._zoom;
|
return this._zoom;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @param {Number} zoom number between 0.3 and 1.9 to set the zoom to */
|
/** @param {Number} zoom number between 0.3 and 1.9 to set the zoom to */
|
||||||
setZoom:function (zoom) {
|
setZoom(zoom) {
|
||||||
this._zoom = zoom;
|
this._zoom = zoom;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @return {@link mindplot.Topic[]} all topics */
|
/** @return {@link mindplot.Topic[]} all topics */
|
||||||
getTopics:function () {
|
getTopics() {
|
||||||
return this._topics;
|
return this._topics;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @return {mindplot.Relationship[]} all relationships */
|
/** @return {mindplot.Relationship[]} all relationships */
|
||||||
getRelationships:function () {
|
getRelationships() {
|
||||||
return this._relationships;
|
return this._relationships;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @return {mindplot.CentralTopic} the central topic */
|
/** @return {mindplot.CentralTopic} the central topic */
|
||||||
getCentralTopic:function () {
|
getCentralTopic() {
|
||||||
var topics = this.getTopics();
|
const topics = this.getTopics();
|
||||||
return topics[0];
|
return topics[0];
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @return {mindplot.Topic[]} selected topics */
|
/** @return {mindplot.Topic[]} selected topics */
|
||||||
filterSelectedTopics:function () {
|
filterSelectedTopics() {
|
||||||
var result = [];
|
const result = [];
|
||||||
for (var i = 0; i < this._topics.length; i++) {
|
for (let i = 0; i < this._topics.length; i++) {
|
||||||
if (this._topics[i].isOnFocus()) {
|
if (this._topics[i].isOnFocus()) {
|
||||||
result.push(this._topics[i]);
|
result.push(this._topics[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {mindplot.Relationship[]} selected relationships
|
* @return {mindplot.Relationship[]} selected relationships
|
||||||
*/
|
*/
|
||||||
filterSelectedRelationships:function () {
|
filterSelectedRelationships() {
|
||||||
var result = [];
|
const result = [];
|
||||||
for (var i = 0; i < this._relationships.length; i++) {
|
for (let i = 0; i < this._relationships.length; i++) {
|
||||||
if (this._relationships[i].isOnFocus()) {
|
if (this._relationships[i].isOnFocus()) {
|
||||||
result.push(this._relationships[i]);
|
result.push(this._relationships[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {Array.<mindplot.Relationship, mindplot.Topic>} all topics and relationships
|
* @return {Array.<mindplot.Relationship, mindplot.Topic>} all topics and relationships
|
||||||
*/
|
*/
|
||||||
getEntities:function () {
|
getEntities() {
|
||||||
var result = [].append(this._topics);
|
const result = [].append(this._topics);
|
||||||
result.append(this._relationships);
|
result.append(this._relationships);
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* removes occurrences of the given topic from the topic array
|
* removes occurrences of the given topic from the topic array
|
||||||
* @param {mindplot.Topic} topic the topic to remove
|
* @param {mindplot.Topic} topic the topic to remove
|
||||||
*/
|
*/
|
||||||
removeTopic:function (topic) {
|
removeTopic(topic) {
|
||||||
$assert(topic, "topic can not be null");
|
$assert(topic, 'topic can not be null');
|
||||||
this._topics.erase(topic);
|
this._topics.erase(topic);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* removes occurrences of the given relationship from the relationship array
|
* removes occurrences of the given relationship from the relationship array
|
||||||
* @param {mindplot.Relationship} rel the relationship to remove
|
* @param {mindplot.Relationship} rel the relationship to remove
|
||||||
*/
|
*/
|
||||||
removeRelationship:function (rel) {
|
removeRelationship(rel) {
|
||||||
$assert(rel, "rel can not be null");
|
$assert(rel, 'rel can not be null');
|
||||||
this._relationships.erase(rel);
|
this._relationships.erase(rel);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* adds the given topic to the topic array
|
* adds the given topic to the topic array
|
||||||
* @param {mindplot.Topic} topic the topic to add
|
* @param {mindplot.Topic} topic the topic to add
|
||||||
* @throws will throw an error if topic is null or undefined
|
* @throws will throw an error if topic is null or undefined
|
||||||
* @throws will throw an error if the topic's id is not a number
|
* @throws will throw an error if the topic's id is not a number
|
||||||
*/
|
*/
|
||||||
addTopic:function (topic) {
|
addTopic(topic) {
|
||||||
$assert(topic, "topic can not be null");
|
$assert(topic, 'topic can not be null');
|
||||||
$assert(typeof topic.getId() == "number", "id is not a number:" + topic.getId());
|
$assert(typeof topic.getId() === 'number', `id is not a number:${topic.getId()}`);
|
||||||
this._topics.push(topic);
|
this._topics.push(topic);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* adds the given relationship to the relationship array
|
* adds the given relationship to the relationship array
|
||||||
* @param {mindplot.Relationship} rel the relationship to add
|
* @param {mindplot.Relationship} rel the relationship to add
|
||||||
* @throws will throw an error if rel is null or undefined
|
* @throws will throw an error if rel is null or undefined
|
||||||
*/
|
*/
|
||||||
addRelationship:function (rel) {
|
addRelationship(rel) {
|
||||||
$assert(rel, "rel can not be null");
|
$assert(rel, 'rel can not be null');
|
||||||
this._relationships.push(rel);
|
this._relationships.push(rel);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Function=} validate a function to validate nodes
|
* @param {Function=} validate a function to validate nodes
|
||||||
* @param {String=} errorMsg an error message to display if the validation fails
|
* @param {String=} errorMsg an error message to display if the validation fails
|
||||||
* @return {String} returns an array of the selected (and, if applicable, valid) topics' ids
|
* @return {String} returns an array of the selected (and, if applicable, valid) topics' ids
|
||||||
*/
|
*/
|
||||||
filterTopicsIds:function (validate, errorMsg) {
|
filterTopicsIds(validate, errorMsg) {
|
||||||
var result = [];
|
const result = [];
|
||||||
var topics = this.filterSelectedTopics();
|
const topics = this.filterSelectedTopics();
|
||||||
|
|
||||||
|
let isValid = true;
|
||||||
|
for (let i = 0; i < topics.length; i++) {
|
||||||
|
const selectedNode = topics[i];
|
||||||
|
if ($defined(validate)) {
|
||||||
|
isValid = validate(selectedNode);
|
||||||
|
}
|
||||||
|
|
||||||
var isValid = true;
|
// Add node only if it's valid.
|
||||||
for (var i = 0; i < topics.length; i++) {
|
if (isValid) {
|
||||||
var selectedNode = topics[i];
|
result.push(selectedNode.getId());
|
||||||
if ($defined(validate)) {
|
} else {
|
||||||
isValid = validate(selectedNode);
|
$notify(errorMsg);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
// Add node only if it's valid.
|
/**
|
||||||
if (isValid) {
|
|
||||||
result.push(selectedNode.getId());
|
|
||||||
} else {
|
|
||||||
$notify(errorMsg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {mindplot.Topic} the first selected topic if one or more are found by the
|
* @return {mindplot.Topic} the first selected topic if one or more are found by the
|
||||||
* filterSelectedTopics function, null otherwise
|
* filterSelectedTopics function, null otherwise
|
||||||
*/
|
*/
|
||||||
selectedTopic:function () {
|
selectedTopic() {
|
||||||
var topics = this.filterSelectedTopics();
|
const topics = this.filterSelectedTopics();
|
||||||
return (topics.length > 0) ? topics[0] : null;
|
return (topics.length > 0) ? topics[0] : null;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {String} id the id of the topic to be retrieved
|
* @param {String} id the id of the topic to be retrieved
|
||||||
* @return {mindplot.Topic} the topic with the respective id
|
* @return {mindplot.Topic} the topic with the respective id
|
||||||
*/
|
*/
|
||||||
findTopicById:function (id) {
|
findTopicById(id) {
|
||||||
var result = null;
|
let result = null;
|
||||||
for (var i = 0; i < this._topics.length; i++) {
|
for (let i = 0; i < this._topics.length; i++) {
|
||||||
var topic = this._topics[i];
|
const topic = this._topics[i];
|
||||||
if (topic.getId() == id) {
|
if (topic.getId() == id) {
|
||||||
result = topic;
|
result = topic;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return result;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default DesignerModel;
|
export default DesignerModel;
|
||||||
|
@ -17,69 +17,69 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const DesignerUndoManager = new Class({
|
const DesignerUndoManager = new Class({
|
||||||
initialize: function(fireChange) {
|
initialize(fireChange) {
|
||||||
this._undoQueue = [];
|
this._undoQueue = [];
|
||||||
this._redoQueue = [];
|
this._redoQueue = [];
|
||||||
this._baseId = 0;
|
this._baseId = 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
enqueue:function(command) {
|
enqueue(command) {
|
||||||
$assert(command, "Command can not be null");
|
$assert(command, 'Command can not be null');
|
||||||
var length = this._undoQueue.length;
|
const { length } = this._undoQueue;
|
||||||
if (command.discardDuplicated && length > 0) {
|
if (command.discardDuplicated && length > 0) {
|
||||||
// Skip duplicated events ...
|
// Skip duplicated events ...
|
||||||
var lastItem = this._undoQueue[length - 1];
|
const lastItem = this._undoQueue[length - 1];
|
||||||
if (lastItem.discardDuplicated != command.discardDuplicated) {
|
if (lastItem.discardDuplicated != command.discardDuplicated) {
|
||||||
this._undoQueue.push(command);
|
this._undoQueue.push(command);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this._undoQueue.push(command);
|
this._undoQueue.push(command);
|
||||||
}
|
|
||||||
this._redoQueue = [];
|
|
||||||
},
|
|
||||||
|
|
||||||
execUndo: function(commandContext) {
|
|
||||||
if (this._undoQueue.length > 0) {
|
|
||||||
var command = this._undoQueue.pop();
|
|
||||||
this._redoQueue.push(command);
|
|
||||||
|
|
||||||
command.undoExecute(commandContext);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
execRedo: function(commandContext) {
|
|
||||||
if (this._redoQueue.length > 0) {
|
|
||||||
var command = this._redoQueue.pop();
|
|
||||||
this._undoQueue.push(command);
|
|
||||||
command.execute(commandContext);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
buildEvent: function() {
|
|
||||||
return {undoSteps: this._undoQueue.length, redoSteps:this._redoQueue.length};
|
|
||||||
},
|
|
||||||
|
|
||||||
markAsChangeBase: function() {
|
|
||||||
var undoLength = this._undoQueue.length;
|
|
||||||
if (undoLength > 0) {
|
|
||||||
var command = this._undoQueue[undoLength - 1];
|
|
||||||
this._baseId = command.getId();
|
|
||||||
} else {
|
|
||||||
this._baseId = 0;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
hasBeenChanged: function() {
|
|
||||||
var result = true;
|
|
||||||
var undoLength= this._undoQueue.length;
|
|
||||||
if (undoLength == 0 && this._baseId == 0) {
|
|
||||||
result = false;
|
|
||||||
} else if (undoLength > 0) {
|
|
||||||
var command = this._undoQueue[undoLength - 1];
|
|
||||||
result = (this._baseId != command.getId());
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
this._redoQueue = [];
|
||||||
|
},
|
||||||
|
|
||||||
|
execUndo(commandContext) {
|
||||||
|
if (this._undoQueue.length > 0) {
|
||||||
|
const command = this._undoQueue.pop();
|
||||||
|
this._redoQueue.push(command);
|
||||||
|
|
||||||
|
command.undoExecute(commandContext);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
execRedo(commandContext) {
|
||||||
|
if (this._redoQueue.length > 0) {
|
||||||
|
const command = this._redoQueue.pop();
|
||||||
|
this._undoQueue.push(command);
|
||||||
|
command.execute(commandContext);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
buildEvent() {
|
||||||
|
return { undoSteps: this._undoQueue.length, redoSteps: this._redoQueue.length };
|
||||||
|
},
|
||||||
|
|
||||||
|
markAsChangeBase() {
|
||||||
|
const undoLength = this._undoQueue.length;
|
||||||
|
if (undoLength > 0) {
|
||||||
|
const command = this._undoQueue[undoLength - 1];
|
||||||
|
this._baseId = command.getId();
|
||||||
|
} else {
|
||||||
|
this._baseId = 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
hasBeenChanged() {
|
||||||
|
let result = true;
|
||||||
|
const undoLength = this._undoQueue.length;
|
||||||
|
if (undoLength == 0 && this._baseId == 0) {
|
||||||
|
result = false;
|
||||||
|
} else if (undoLength > 0) {
|
||||||
|
const command = this._undoQueue[undoLength - 1];
|
||||||
|
result = (this._baseId != command.getId());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default DesignerUndoManager;
|
export default DesignerUndoManager;
|
||||||
|
@ -17,99 +17,94 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const DragConnector = new Class({
|
const DragConnector = new Class({
|
||||||
initialize:function (designerModel, workspace) {
|
initialize(designerModel, workspace) {
|
||||||
$assert(designerModel, 'designerModel can not be null');
|
$assert(designerModel, 'designerModel can not be null');
|
||||||
$assert(workspace, 'workspace can not be null');
|
$assert(workspace, 'workspace can not be null');
|
||||||
|
|
||||||
// this._layoutManager = layoutManager;
|
// this._layoutManager = layoutManager;
|
||||||
this._designerModel = designerModel;
|
this._designerModel = designerModel;
|
||||||
this._workspace = workspace;
|
this._workspace = workspace;
|
||||||
},
|
},
|
||||||
|
|
||||||
checkConnection:function (dragTopic) {
|
checkConnection(dragTopic) {
|
||||||
var topics = this._designerModel.getTopics();
|
const topics = this._designerModel.getTopics();
|
||||||
|
|
||||||
// Must be disconnected from their current connection ?.
|
// Must be disconnected from their current connection ?.
|
||||||
var candidates = this._searchConnectionCandidates(dragTopic);
|
const candidates = this._searchConnectionCandidates(dragTopic);
|
||||||
var currentConnection = dragTopic.getConnectedToTopic();
|
const currentConnection = dragTopic.getConnectedToTopic();
|
||||||
|
|
||||||
|
|
||||||
if (currentConnection && (candidates.length == 0 || candidates[0] != currentConnection)) {
|
|
||||||
dragTopic.disconnect(this._workspace);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally, connect nodes ...
|
|
||||||
if (!dragTopic.isConnected() && candidates.length > 0) {
|
|
||||||
dragTopic.connectTo(candidates[0]);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_searchConnectionCandidates:function (dragTopic) {
|
|
||||||
var topics = this._designerModel.getTopics();
|
|
||||||
var draggedNode = dragTopic.getDraggedTopic();
|
|
||||||
|
|
||||||
// Drag node connects to the border ...
|
|
||||||
var dragTopicWidth = dragTopic.getSize ? dragTopic.getSize().width : 0; // Hack...
|
|
||||||
var xMouseGap = dragTopic.getPosition().x > 0 ? 0 : dragTopicWidth;
|
|
||||||
var sPos = {x:dragTopic.getPosition().x - xMouseGap, y:dragTopic.getPosition().y};
|
|
||||||
|
|
||||||
// Perform a initial filter to discard topics:
|
|
||||||
// - Exclude dragged topic
|
|
||||||
// - Exclude dragTopic pivot
|
|
||||||
// - Nodes that are collapsed
|
|
||||||
// - It's not part of the branch dragged itself
|
|
||||||
topics = topics.filter(function (topic) {
|
|
||||||
var result = draggedNode != topic;
|
|
||||||
result = result && topic != draggedNode;
|
|
||||||
result = result && !topic.areChildrenShrunken() && !topic.isCollapsed();
|
|
||||||
result = result && !draggedNode.isChildTopic(topic);
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Filter all the nodes that are outside the vertical boundary:
|
|
||||||
// * The node is to out of the x scope
|
|
||||||
// * The x distance greater the vertical tolerated distance
|
|
||||||
topics = topics.filter(function (topic) {
|
|
||||||
var tpos = topic.getPosition();
|
|
||||||
// Center topic has different alignment than the rest of the nodes. That's why i need to divide it by two...
|
|
||||||
var txborder = tpos.x + (topic.getSize().width / 2) * Math.sign(sPos.x);
|
|
||||||
var distance = (sPos.x - txborder) * Math.sign(sPos.x);
|
|
||||||
return distance > 0 && (distance < DragConnector.MAX_VERTICAL_CONNECTION_TOLERANCE);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// Assign a priority based on the distance:
|
|
||||||
// - Alignment with the targetNode
|
|
||||||
// - Vertical distance
|
|
||||||
// - Horizontal proximity
|
|
||||||
// - It's already connected.
|
|
||||||
var currentConnection = dragTopic.getConnectedToTopic();
|
|
||||||
var me = this;
|
|
||||||
topics = topics.sort(function (a, b) {
|
|
||||||
var aPos = a.getPosition();
|
|
||||||
var bPos = b.getPosition();
|
|
||||||
|
|
||||||
var av = me._isVerticallyAligned(a.getSize(), aPos, sPos);
|
|
||||||
var bv = me._isVerticallyAligned(b.getSize(), bPos, sPos);
|
|
||||||
return me._proximityWeight(av, a, sPos, currentConnection) - me._proximityWeight(bv, b, sPos, currentConnection);
|
|
||||||
|
|
||||||
});
|
|
||||||
return topics;
|
|
||||||
},
|
|
||||||
|
|
||||||
_proximityWeight:function (isAligned, target, sPos, currentConnection) {
|
|
||||||
var tPos = target.getPosition();
|
|
||||||
return (isAligned ? 0 : 200 ) + Math.abs(tPos.x - sPos.x) + Math.abs(tPos.y - sPos.y) + (currentConnection == target ? 0 : 100);
|
|
||||||
},
|
|
||||||
|
|
||||||
_isVerticallyAligned:function (targetSize, targetPosition, sourcePosition) {
|
|
||||||
|
|
||||||
return Math.abs(sourcePosition.y - targetPosition.y) < targetSize.height / 2;
|
|
||||||
|
|
||||||
|
if (currentConnection && (candidates.length == 0 || candidates[0] != currentConnection)) {
|
||||||
|
dragTopic.disconnect(this._workspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Finally, connect nodes ...
|
||||||
|
if (!dragTopic.isConnected() && candidates.length > 0) {
|
||||||
|
dragTopic.connectTo(candidates[0]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_searchConnectionCandidates(dragTopic) {
|
||||||
|
let topics = this._designerModel.getTopics();
|
||||||
|
const draggedNode = dragTopic.getDraggedTopic();
|
||||||
|
|
||||||
|
// Drag node connects to the border ...
|
||||||
|
const dragTopicWidth = dragTopic.getSize ? dragTopic.getSize().width : 0; // Hack...
|
||||||
|
const xMouseGap = dragTopic.getPosition().x > 0 ? 0 : dragTopicWidth;
|
||||||
|
const sPos = { x: dragTopic.getPosition().x - xMouseGap, y: dragTopic.getPosition().y };
|
||||||
|
|
||||||
|
// Perform a initial filter to discard topics:
|
||||||
|
// - Exclude dragged topic
|
||||||
|
// - Exclude dragTopic pivot
|
||||||
|
// - Nodes that are collapsed
|
||||||
|
// - It's not part of the branch dragged itself
|
||||||
|
topics = topics.filter((topic) => {
|
||||||
|
let result = draggedNode != topic;
|
||||||
|
result = result && topic != draggedNode;
|
||||||
|
result = result && !topic.areChildrenShrunken() && !topic.isCollapsed();
|
||||||
|
result = result && !draggedNode.isChildTopic(topic);
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Filter all the nodes that are outside the vertical boundary:
|
||||||
|
// * The node is to out of the x scope
|
||||||
|
// * The x distance greater the vertical tolerated distance
|
||||||
|
topics = topics.filter((topic) => {
|
||||||
|
const tpos = topic.getPosition();
|
||||||
|
// Center topic has different alignment than the rest of the nodes. That's why i need to divide it by two...
|
||||||
|
const txborder = tpos.x + (topic.getSize().width / 2) * Math.sign(sPos.x);
|
||||||
|
const distance = (sPos.x - txborder) * Math.sign(sPos.x);
|
||||||
|
return distance > 0 && (distance < DragConnector.MAX_VERTICAL_CONNECTION_TOLERANCE);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assign a priority based on the distance:
|
||||||
|
// - Alignment with the targetNode
|
||||||
|
// - Vertical distance
|
||||||
|
// - Horizontal proximity
|
||||||
|
// - It's already connected.
|
||||||
|
const currentConnection = dragTopic.getConnectedToTopic();
|
||||||
|
const me = this;
|
||||||
|
topics = topics.sort((a, b) => {
|
||||||
|
const aPos = a.getPosition();
|
||||||
|
const bPos = b.getPosition();
|
||||||
|
|
||||||
|
const av = me._isVerticallyAligned(a.getSize(), aPos, sPos);
|
||||||
|
const bv = me._isVerticallyAligned(b.getSize(), bPos, sPos);
|
||||||
|
return me._proximityWeight(av, a, sPos, currentConnection) - me._proximityWeight(bv, b, sPos, currentConnection);
|
||||||
|
});
|
||||||
|
return topics;
|
||||||
|
},
|
||||||
|
|
||||||
|
_proximityWeight(isAligned, target, sPos, currentConnection) {
|
||||||
|
const tPos = target.getPosition();
|
||||||
|
return (isAligned ? 0 : 200) + Math.abs(tPos.x - sPos.x) + Math.abs(tPos.y - sPos.y) + (currentConnection == target ? 0 : 100);
|
||||||
|
},
|
||||||
|
|
||||||
|
_isVerticallyAligned(targetSize, targetPosition, sourcePosition) {
|
||||||
|
return Math.abs(sourcePosition.y - targetPosition.y) < targetSize.height / 2;
|
||||||
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
DragConnector.MAX_VERTICAL_CONNECTION_TOLERANCE = 80;
|
DragConnector.MAX_VERTICAL_CONNECTION_TOLERANCE = 80;
|
||||||
|
|
||||||
export default DragConnector
|
export default DragConnector;
|
||||||
|
@ -18,134 +18,129 @@
|
|||||||
const DragTopic = require('./DragTopic').default;
|
const DragTopic = require('./DragTopic').default;
|
||||||
|
|
||||||
const DragManager = new Class({
|
const DragManager = new Class({
|
||||||
initialize:function(workspace, eventDispatcher) {
|
initialize(workspace, eventDispatcher) {
|
||||||
this._workspace = workspace;
|
this._workspace = workspace;
|
||||||
this._designerModel = workspace;
|
this._designerModel = workspace;
|
||||||
this._listeners = {};
|
this._listeners = {};
|
||||||
this._isDragInProcess = false;
|
this._isDragInProcess = false;
|
||||||
this._eventDispatcher = eventDispatcher;
|
this._eventDispatcher = eventDispatcher;
|
||||||
DragTopic.init(this._workspace);
|
DragTopic.init(this._workspace);
|
||||||
},
|
},
|
||||||
|
|
||||||
add : function(node) {
|
add(node) {
|
||||||
// Add behaviour ...
|
// Add behaviour ...
|
||||||
var workspace = this._workspace;
|
const workspace = this._workspace;
|
||||||
var screen = workspace.getScreenManager();
|
const screen = workspace.getScreenManager();
|
||||||
var dragManager = this;
|
const dragManager = this;
|
||||||
var me = this;
|
const me = this;
|
||||||
var mouseDownListener = function(event) {
|
const mouseDownListener = function (event) {
|
||||||
if (workspace.isWorkspaceEventsEnabled()) {
|
if (workspace.isWorkspaceEventsEnabled()) {
|
||||||
// Disable double drag...
|
// Disable double drag...
|
||||||
workspace.enableWorkspaceEvents(false);
|
workspace.enableWorkspaceEvents(false);
|
||||||
|
|
||||||
// Set initial position.
|
// Set initial position.
|
||||||
var layoutManager = me._eventDispatcher.getLayoutManager();
|
const layoutManager = me._eventDispatcher.getLayoutManager();
|
||||||
var dragNode = node.createDragNode(layoutManager);
|
const dragNode = node.createDragNode(layoutManager);
|
||||||
|
|
||||||
// Register mouse move listener ...
|
// Register mouse move listener ...
|
||||||
var mouseMoveListener = dragManager._buildMouseMoveListener(workspace, dragNode, dragManager);
|
const mouseMoveListener = dragManager._buildMouseMoveListener(workspace, dragNode, dragManager);
|
||||||
screen.addEvent('mousemove', mouseMoveListener);
|
screen.addEvent('mousemove', mouseMoveListener);
|
||||||
|
|
||||||
// Register mouse up listeners ...
|
// Register mouse up listeners ...
|
||||||
var mouseUpListener = dragManager._buildMouseUpListener(workspace, node, dragNode, dragManager);
|
const mouseUpListener = dragManager._buildMouseUpListener(workspace, node, dragNode, dragManager);
|
||||||
screen.addEvent('mouseup', mouseUpListener);
|
screen.addEvent('mouseup', mouseUpListener);
|
||||||
|
|
||||||
// Change cursor.
|
// Change cursor.
|
||||||
window.document.body.style.cursor = 'move';
|
window.document.body.style.cursor = 'move';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
node.addEvent('mousedown', mouseDownListener);
|
node.addEvent('mousedown', mouseDownListener);
|
||||||
},
|
},
|
||||||
|
|
||||||
remove : function(node) {
|
remove(node) {
|
||||||
var nodes = this._topics;
|
const nodes = this._topics;
|
||||||
var contained = false;
|
let contained = false;
|
||||||
var index = -1;
|
let index = -1;
|
||||||
for (var i = 0; i < nodes.length; i++) {
|
for (let i = 0; i < nodes.length; i++) {
|
||||||
if (nodes[i] == node) {
|
if (nodes[i] == node) {
|
||||||
contained = true;
|
contained = true;
|
||||||
index = i;
|
index = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_buildMouseMoveListener : function(workspace, dragNode, dragManager) {
|
_buildMouseMoveListener(workspace, dragNode, dragManager) {
|
||||||
var screen = workspace.getScreenManager();
|
const screen = workspace.getScreenManager();
|
||||||
var me = this;
|
const me = this;
|
||||||
var result = function(event) {
|
const result = function (event) {
|
||||||
|
if (!me._isDragInProcess) {
|
||||||
|
// Execute Listeners ..
|
||||||
|
const startDragListener = dragManager._listeners.startdragging;
|
||||||
|
startDragListener(event, dragNode);
|
||||||
|
|
||||||
if (!me._isDragInProcess) {
|
// Add shadow node to the workspace.
|
||||||
// Execute Listeners ..
|
workspace.append(dragNode);
|
||||||
var startDragListener = dragManager._listeners['startdragging'];
|
|
||||||
startDragListener(event, dragNode);
|
|
||||||
|
|
||||||
// Add shadow node to the workspace.
|
me._isDragInProcess = true;
|
||||||
workspace.append(dragNode);
|
}
|
||||||
|
|
||||||
me._isDragInProcess = true;
|
const pos = screen.getWorkspaceMousePosition(event);
|
||||||
}
|
dragNode.setPosition(pos.x, pos.y);
|
||||||
|
|
||||||
var pos = screen.getWorkspaceMousePosition(event);
|
// Call mouse move listeners ...
|
||||||
dragNode.setPosition(pos.x, pos.y);
|
const dragListener = dragManager._listeners.dragging;
|
||||||
|
if ($defined(dragListener)) {
|
||||||
|
dragListener(event, dragNode);
|
||||||
|
}
|
||||||
|
|
||||||
// Call mouse move listeners ...
|
event.preventDefault();
|
||||||
var dragListener = dragManager._listeners['dragging'];
|
};
|
||||||
if ($defined(dragListener)) {
|
dragManager._mouseMoveListener = result;
|
||||||
dragListener(event, dragNode);
|
return result;
|
||||||
}
|
},
|
||||||
|
|
||||||
event.preventDefault();
|
_buildMouseUpListener(workspace, node, dragNode, dragManager) {
|
||||||
|
const screen = workspace.getScreenManager();
|
||||||
|
const me = this;
|
||||||
|
const result = function (event) {
|
||||||
|
$assert(dragNode.isDragTopic, 'dragNode must be an DragTopic');
|
||||||
|
|
||||||
};
|
// Remove all the events.
|
||||||
dragManager._mouseMoveListener = result;
|
screen.removeEvent('mousemove', dragManager._mouseMoveListener);
|
||||||
return result;
|
screen.removeEvent('mouseup', dragManager._mouseUpListener);
|
||||||
},
|
|
||||||
|
|
||||||
_buildMouseUpListener : function(workspace, node, dragNode, dragManager) {
|
// Help GC
|
||||||
var screen = workspace.getScreenManager();
|
dragManager._mouseMoveListener = null;
|
||||||
var me = this;
|
dragManager._mouseUpListener = null;
|
||||||
var result = function(event) {
|
|
||||||
$assert(dragNode.isDragTopic, 'dragNode must be an DragTopic');
|
|
||||||
|
|
||||||
// Remove all the events.
|
workspace.enableWorkspaceEvents(true);
|
||||||
screen.removeEvent('mousemove', dragManager._mouseMoveListener);
|
// Change the cursor to the default.
|
||||||
screen.removeEvent('mouseup', dragManager._mouseUpListener);
|
window.document.body.style.cursor = 'default';
|
||||||
|
|
||||||
// Help GC
|
if (me._isDragInProcess) {
|
||||||
dragManager._mouseMoveListener = null;
|
// Execute Listeners only if the node has been moved.
|
||||||
dragManager._mouseUpListener = null;
|
const endDragListener = dragManager._listeners.enddragging;
|
||||||
|
endDragListener(event, dragNode);
|
||||||
|
|
||||||
workspace.enableWorkspaceEvents(true);
|
// Remove drag node from the workspace.
|
||||||
// Change the cursor to the default.
|
dragNode.removeFromWorkspace(workspace);
|
||||||
window.document.body.style.cursor = 'default';
|
|
||||||
|
|
||||||
if (me._isDragInProcess) {
|
me._isDragInProcess = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
dragManager._mouseUpListener = result;
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
// Execute Listeners only if the node has been moved.
|
/**
|
||||||
var endDragListener = dragManager._listeners['enddragging'];
|
|
||||||
endDragListener(event, dragNode);
|
|
||||||
|
|
||||||
// Remove drag node from the workspace.
|
|
||||||
dragNode.removeFromWorkspace(workspace);
|
|
||||||
|
|
||||||
me._isDragInProcess = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
dragManager._mouseUpListener = result;
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* type:
|
* type:
|
||||||
* - startdragging.
|
* - startdragging.
|
||||||
* - dragging
|
* - dragging
|
||||||
* - enddragging
|
* - enddragging
|
||||||
*/
|
*/
|
||||||
addEvent : function(type, listener) {
|
addEvent(type, listener) {
|
||||||
this._listeners[type] = listener;
|
this._listeners[type] = listener;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default DragManager;
|
export default DragManager;
|
||||||
|
@ -15,9 +15,11 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
const Core = require('@wismapping/core-js')
|
const Core = require('@wismapping/core-js');
|
||||||
|
|
||||||
const core = Core();
|
const core = Core();
|
||||||
const web2D = require('@wismapping/web2d')
|
const web2D = require('@wismapping/web2d');
|
||||||
|
|
||||||
const web2d = web2D();
|
const web2d = web2D();
|
||||||
|
|
||||||
const DragTopic = require('./DragTopic').default;
|
const DragTopic = require('./DragTopic').default;
|
||||||
@ -25,214 +27,214 @@ const Shape = require('./util/Shape').default;
|
|||||||
const INodeModel = require('./model/INodeModel').default;
|
const INodeModel = require('./model/INodeModel').default;
|
||||||
|
|
||||||
const DragPivot = new Class({
|
const DragPivot = new Class({
|
||||||
initialize:function() {
|
initialize() {
|
||||||
this._position = new core.Point();
|
this._position = new core.Point();
|
||||||
this._size = DragTopic.PIVOT_SIZE;
|
this._size = DragTopic.PIVOT_SIZE;
|
||||||
|
|
||||||
this._straightLine = this._buildStraightLine();
|
this._straightLine = this._buildStraightLine();
|
||||||
this._curvedLine = this._buildCurvedLine();
|
this._curvedLine = this._buildCurvedLine();
|
||||||
this._dragPivot = this._buildRect();
|
this._dragPivot = this._buildRect();
|
||||||
this._connectRect = this._buildRect();
|
this._connectRect = this._buildRect();
|
||||||
this._targetTopic = null;
|
this._targetTopic = null;
|
||||||
this._isVisible = false;
|
this._isVisible = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
isVisible:function() {
|
isVisible() {
|
||||||
return this._isVisible;
|
return this._isVisible;
|
||||||
},
|
},
|
||||||
|
|
||||||
getTargetTopic : function() {
|
getTargetTopic() {
|
||||||
return this._targetTopic;
|
return this._targetTopic;
|
||||||
},
|
},
|
||||||
|
|
||||||
_buildStraightLine : function() {
|
_buildStraightLine() {
|
||||||
var line = new web2d.CurvedLine();
|
const line = new web2d.CurvedLine();
|
||||||
line.setStyle(web2d.CurvedLine.SIMPLE_LINE);
|
line.setStyle(web2d.CurvedLine.SIMPLE_LINE);
|
||||||
line.setStroke(1, 'solid', '#CC0033');
|
line.setStroke(1, 'solid', '#CC0033');
|
||||||
line.setOpacity(0.4);
|
line.setOpacity(0.4);
|
||||||
line.setVisibility(false);
|
line.setVisibility(false);
|
||||||
return line;
|
return line;
|
||||||
},
|
},
|
||||||
|
|
||||||
_buildCurvedLine : function() {
|
_buildCurvedLine() {
|
||||||
var line = new web2d.CurvedLine();
|
const line = new web2d.CurvedLine();
|
||||||
line.setStyle(web2d.CurvedLine.SIMPLE_LINE);
|
line.setStyle(web2d.CurvedLine.SIMPLE_LINE);
|
||||||
line.setStroke(1, 'solid', '#CC0033');
|
line.setStroke(1, 'solid', '#CC0033');
|
||||||
line.setOpacity(0.4);
|
line.setOpacity(0.4);
|
||||||
line.setVisibility(false);
|
line.setVisibility(false);
|
||||||
return line;
|
return line;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_redrawLine() {
|
||||||
|
// Update line position.
|
||||||
|
$assert(this.getTargetTopic(), 'Illegal invocation. Target node can not be null');
|
||||||
|
|
||||||
_redrawLine : function() {
|
const pivotRect = this._getPivotRect();
|
||||||
// Update line position.
|
|
||||||
$assert(this.getTargetTopic(), 'Illegal invocation. Target node can not be null');
|
|
||||||
|
|
||||||
var pivotRect = this._getPivotRect();
|
// Pivot position has not changed. In this case, position change is not required.
|
||||||
|
const targetTopic = this.getTargetTopic();
|
||||||
|
const position = this._position;
|
||||||
|
|
||||||
// Pivot position has not changed. In this case, position change is not required.
|
// Calculate pivot connection point ...
|
||||||
var targetTopic = this.getTargetTopic();
|
const size = this._size;
|
||||||
var position = this._position;
|
const targetPosition = targetTopic.getPosition();
|
||||||
|
const line = this._getConnectionLine();
|
||||||
|
|
||||||
// Calculate pivot connection point ...
|
// Update Line position.
|
||||||
var size = this._size;
|
const isAtRight = Shape.isAtRight(targetPosition, position);
|
||||||
var targetPosition = targetTopic.getPosition();
|
const pivotPoint = Shape.calculateRectConnectionPoint(position, size, isAtRight);
|
||||||
var line = this._getConnectionLine();
|
line.setFrom(pivotPoint.x, pivotPoint.y);
|
||||||
|
|
||||||
// Update Line position.
|
// Update rect position
|
||||||
var isAtRight = Shape.isAtRight(targetPosition, position);
|
const cx = position.x - (parseInt(size.width) / 2);
|
||||||
var pivotPoint = Shape.calculateRectConnectionPoint(position, size, isAtRight);
|
const cy = position.y - (parseInt(size.height) / 2);
|
||||||
line.setFrom(pivotPoint.x, pivotPoint.y);
|
pivotRect.setPosition(cx, cy);
|
||||||
|
|
||||||
// Update rect position
|
// Make line visible only when the position has been already changed.
|
||||||
var cx = position.x - (parseInt(size.width) / 2);
|
// This solve several strange effects ;)
|
||||||
var cy = position.y - (parseInt(size.height) / 2);
|
const targetPoint = targetTopic.workoutIncomingConnectionPoint(pivotPoint);
|
||||||
pivotRect.setPosition(cx, cy);
|
line.setTo(targetPoint.x, targetPoint.y);
|
||||||
|
},
|
||||||
|
|
||||||
// Make line visible only when the position has been already changed.
|
setPosition(point) {
|
||||||
// This solve several strange effects ;)
|
this._position = point;
|
||||||
var targetPoint = targetTopic.workoutIncomingConnectionPoint(pivotPoint);
|
this._redrawLine();
|
||||||
line.setTo(targetPoint.x, targetPoint.y);
|
},
|
||||||
},
|
|
||||||
|
|
||||||
setPosition : function(point) {
|
getPosition() {
|
||||||
this._position = point;
|
return this._position;
|
||||||
this._redrawLine();
|
},
|
||||||
},
|
|
||||||
|
|
||||||
getPosition : function() {
|
_buildRect() {
|
||||||
return this._position;
|
const size = this._size;
|
||||||
},
|
const rectAttributes = {
|
||||||
|
fillColor: '#CC0033', opacity: 0.4, width: size.width, height: size.height, strokeColor: '#FF9933',
|
||||||
|
};
|
||||||
|
const rect = new web2d.Rect(0, rectAttributes);
|
||||||
|
rect.setVisibility(false);
|
||||||
|
return rect;
|
||||||
|
},
|
||||||
|
|
||||||
_buildRect : function() {
|
_getPivotRect() {
|
||||||
var size = this._size;
|
return this._dragPivot;
|
||||||
var rectAttributes = {fillColor:'#CC0033',opacity:0.4,width:size.width,height:size.height,strokeColor:'#FF9933'};
|
},
|
||||||
var rect = new web2d.Rect(0, rectAttributes);
|
|
||||||
rect.setVisibility(false);
|
|
||||||
return rect;
|
|
||||||
},
|
|
||||||
|
|
||||||
_getPivotRect : function() {
|
getSize() {
|
||||||
return this._dragPivot;
|
const elem2d = this._getPivotRect();
|
||||||
},
|
return elem2d.getSize();
|
||||||
|
},
|
||||||
|
|
||||||
getSize : function() {
|
setVisibility(value) {
|
||||||
var elem2d = this._getPivotRect();
|
if (this.isVisible() != value) {
|
||||||
return elem2d.getSize();
|
const pivotRect = this._getPivotRect();
|
||||||
},
|
pivotRect.setVisibility(value);
|
||||||
|
|
||||||
setVisibility : function(value) {
|
const connectRect = this._connectRect;
|
||||||
if (this.isVisible() != value) {
|
connectRect.setVisibility(value);
|
||||||
|
|
||||||
var pivotRect = this._getPivotRect();
|
const line = this._getConnectionLine();
|
||||||
pivotRect.setVisibility(value);
|
if (line) {
|
||||||
|
line.setVisibility(value);
|
||||||
var connectRect = this._connectRect;
|
}
|
||||||
connectRect.setVisibility(value);
|
this._isVisible = value;
|
||||||
|
|
||||||
var line = this._getConnectionLine();
|
|
||||||
if (line) {
|
|
||||||
line.setVisibility(value);
|
|
||||||
}
|
|
||||||
this._isVisible = value;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// If the node is connected, validate that there is a line connecting both...
|
|
||||||
_getConnectionLine : function() {
|
|
||||||
var result = null;
|
|
||||||
var parentTopic = this._targetTopic;
|
|
||||||
if (parentTopic) {
|
|
||||||
if (parentTopic.getType() == INodeModel.CENTRAL_TOPIC_TYPE) {
|
|
||||||
result = this._straightLine;
|
|
||||||
} else {
|
|
||||||
result = this._curvedLine;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
addToWorkspace : function(workspace) {
|
|
||||||
var pivotRect = this._getPivotRect();
|
|
||||||
workspace.append(pivotRect);
|
|
||||||
|
|
||||||
var connectToRect = this._connectRect;
|
|
||||||
workspace.append(connectToRect);
|
|
||||||
|
|
||||||
// Add a hidden straight line ...
|
|
||||||
var straighLine = this._straightLine;
|
|
||||||
straighLine.setVisibility(false);
|
|
||||||
workspace.append(straighLine);
|
|
||||||
straighLine.moveToBack();
|
|
||||||
|
|
||||||
// Add a hidden curved line ...
|
|
||||||
var curvedLine = this._curvedLine;
|
|
||||||
curvedLine.setVisibility(false);
|
|
||||||
workspace.append(curvedLine);
|
|
||||||
curvedLine.moveToBack();
|
|
||||||
|
|
||||||
// Add a connect rect ...
|
|
||||||
var connectRect = this._connectRect;
|
|
||||||
connectRect.setVisibility(false);
|
|
||||||
workspace.append(connectRect);
|
|
||||||
connectRect.moveToBack();
|
|
||||||
},
|
|
||||||
|
|
||||||
removeFromWorkspace : function(workspace) {
|
|
||||||
var shape = this._getPivotRect();
|
|
||||||
workspace.removeChild(shape);
|
|
||||||
|
|
||||||
var connectToRect = this._connectRect;
|
|
||||||
workspace.removeChild(connectToRect);
|
|
||||||
|
|
||||||
if ($defined(this._straightLine)) {
|
|
||||||
workspace.removeChild(this._straightLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($defined(this._curvedLine)) {
|
|
||||||
workspace.removeChild(this._curvedLine);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
connectTo : function(targetTopic, position) {
|
|
||||||
$assert(!this._outgoingLine, 'Could not connect an already connected node');
|
|
||||||
$assert(targetTopic != this, 'Circular connection are not allowed');
|
|
||||||
$assert(position, 'position can not be null');
|
|
||||||
$assert(targetTopic, 'parent can not be null');
|
|
||||||
|
|
||||||
this._position = position;
|
|
||||||
this._targetTopic = targetTopic;
|
|
||||||
|
|
||||||
// Connected to Rect ...
|
|
||||||
var connectRect = this._connectRect;
|
|
||||||
var targetSize = targetTopic.getSize();
|
|
||||||
|
|
||||||
// Add 4 pixel in order to keep create a rect bigger than the topic.
|
|
||||||
var width = targetSize.width + 4;
|
|
||||||
var height = targetSize.height + 4;
|
|
||||||
|
|
||||||
connectRect.setSize(width, height);
|
|
||||||
|
|
||||||
var targetPosition = targetTopic.getPosition();
|
|
||||||
var cx = Math.ceil(targetPosition.x - (width / 2));
|
|
||||||
var cy = Math.ceil(targetPosition.y - (height / 2));
|
|
||||||
connectRect.setPosition(cx, cy);
|
|
||||||
|
|
||||||
// Change elements position ...
|
|
||||||
var pivotRect = this._getPivotRect();
|
|
||||||
pivotRect.moveToFront();
|
|
||||||
pivotRect.setPosition(position.x, position.y);
|
|
||||||
|
|
||||||
this._redrawLine();
|
|
||||||
},
|
|
||||||
|
|
||||||
disconnect : function(workspace) {
|
|
||||||
$assert(workspace, 'workspace can not be null.');
|
|
||||||
$assert(this._targetTopic, 'There are not connected topic.');
|
|
||||||
|
|
||||||
this.setVisibility(false);
|
|
||||||
this._targetTopic = null;
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// If the node is connected, validate that there is a line connecting both...
|
||||||
|
_getConnectionLine() {
|
||||||
|
let result = null;
|
||||||
|
const parentTopic = this._targetTopic;
|
||||||
|
if (parentTopic) {
|
||||||
|
if (parentTopic.getType() == INodeModel.CENTRAL_TOPIC_TYPE) {
|
||||||
|
result = this._straightLine;
|
||||||
|
} else {
|
||||||
|
result = this._curvedLine;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
addToWorkspace(workspace) {
|
||||||
|
const pivotRect = this._getPivotRect();
|
||||||
|
workspace.append(pivotRect);
|
||||||
|
|
||||||
|
const connectToRect = this._connectRect;
|
||||||
|
workspace.append(connectToRect);
|
||||||
|
|
||||||
|
// Add a hidden straight line ...
|
||||||
|
const straighLine = this._straightLine;
|
||||||
|
straighLine.setVisibility(false);
|
||||||
|
workspace.append(straighLine);
|
||||||
|
straighLine.moveToBack();
|
||||||
|
|
||||||
|
// Add a hidden curved line ...
|
||||||
|
const curvedLine = this._curvedLine;
|
||||||
|
curvedLine.setVisibility(false);
|
||||||
|
workspace.append(curvedLine);
|
||||||
|
curvedLine.moveToBack();
|
||||||
|
|
||||||
|
// Add a connect rect ...
|
||||||
|
const connectRect = this._connectRect;
|
||||||
|
connectRect.setVisibility(false);
|
||||||
|
workspace.append(connectRect);
|
||||||
|
connectRect.moveToBack();
|
||||||
|
},
|
||||||
|
|
||||||
|
removeFromWorkspace(workspace) {
|
||||||
|
const shape = this._getPivotRect();
|
||||||
|
workspace.removeChild(shape);
|
||||||
|
|
||||||
|
const connectToRect = this._connectRect;
|
||||||
|
workspace.removeChild(connectToRect);
|
||||||
|
|
||||||
|
if ($defined(this._straightLine)) {
|
||||||
|
workspace.removeChild(this._straightLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($defined(this._curvedLine)) {
|
||||||
|
workspace.removeChild(this._curvedLine);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
connectTo(targetTopic, position) {
|
||||||
|
$assert(!this._outgoingLine, 'Could not connect an already connected node');
|
||||||
|
$assert(targetTopic != this, 'Circular connection are not allowed');
|
||||||
|
$assert(position, 'position can not be null');
|
||||||
|
$assert(targetTopic, 'parent can not be null');
|
||||||
|
|
||||||
|
this._position = position;
|
||||||
|
this._targetTopic = targetTopic;
|
||||||
|
|
||||||
|
// Connected to Rect ...
|
||||||
|
const connectRect = this._connectRect;
|
||||||
|
const targetSize = targetTopic.getSize();
|
||||||
|
|
||||||
|
// Add 4 pixel in order to keep create a rect bigger than the topic.
|
||||||
|
const width = targetSize.width + 4;
|
||||||
|
const height = targetSize.height + 4;
|
||||||
|
|
||||||
|
connectRect.setSize(width, height);
|
||||||
|
|
||||||
|
const targetPosition = targetTopic.getPosition();
|
||||||
|
const cx = Math.ceil(targetPosition.x - (width / 2));
|
||||||
|
const cy = Math.ceil(targetPosition.y - (height / 2));
|
||||||
|
connectRect.setPosition(cx, cy);
|
||||||
|
|
||||||
|
// Change elements position ...
|
||||||
|
const pivotRect = this._getPivotRect();
|
||||||
|
pivotRect.moveToFront();
|
||||||
|
pivotRect.setPosition(position.x, position.y);
|
||||||
|
|
||||||
|
this._redrawLine();
|
||||||
|
},
|
||||||
|
|
||||||
|
disconnect(workspace) {
|
||||||
|
$assert(workspace, 'workspace can not be null.');
|
||||||
|
$assert(this._targetTopic, 'There are not connected topic.');
|
||||||
|
|
||||||
|
this.setVisibility(false);
|
||||||
|
this._targetTopic = null;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default DragPivot;
|
export default DragPivot;
|
||||||
|
@ -15,207 +15,206 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
const Core = require('@wismapping/core-js')
|
const Core = require('@wismapping/core-js');
|
||||||
|
|
||||||
const core = Core();
|
const core = Core();
|
||||||
|
|
||||||
const ActionDispatcher = require('./ActionDispatcher').default
|
const ActionDispatcher = require('./ActionDispatcher').default;
|
||||||
const DragPivot = require('./DragPivot').default;
|
const DragPivot = require('./DragPivot').default;
|
||||||
|
|
||||||
const DragTopic = new Class({
|
const DragTopic = new Class({
|
||||||
initialize:function (dragShape, draggedNode, layoutManger) {
|
initialize(dragShape, draggedNode, layoutManger) {
|
||||||
$assert(dragShape, 'Rect can not be null.');
|
$assert(dragShape, 'Rect can not be null.');
|
||||||
$assert(draggedNode, 'draggedNode can not be null.');
|
$assert(draggedNode, 'draggedNode can not be null.');
|
||||||
$assert(layoutManger, 'layoutManger can not be null.');
|
$assert(layoutManger, 'layoutManger can not be null.');
|
||||||
|
|
||||||
this._elem2d = dragShape;
|
this._elem2d = dragShape;
|
||||||
this._order = null;
|
this._order = null;
|
||||||
this._draggedNode = draggedNode;
|
this._draggedNode = draggedNode;
|
||||||
this._layoutManager = layoutManger;
|
this._layoutManager = layoutManger;
|
||||||
this._position = new core.Point();
|
this._position = new core.Point();
|
||||||
this._isInWorkspace = false;
|
this._isInWorkspace = false;
|
||||||
this._isFreeLayoutEnabled = false;
|
this._isFreeLayoutEnabled = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
setOrder:function (order) {
|
setOrder(order) {
|
||||||
this._order = order;
|
this._order = order;
|
||||||
},
|
},
|
||||||
|
|
||||||
setPosition:function (x, y) {
|
setPosition(x, y) {
|
||||||
// Update drag shadow position ....
|
// Update drag shadow position ....
|
||||||
var position = {x:x, y:y};
|
let position = { x, y };
|
||||||
if (this.isFreeLayoutOn() && this.isConnected()) {
|
if (this.isFreeLayoutOn() && this.isConnected()) {
|
||||||
var _layoutManager = this._layoutManager;
|
const { _layoutManager } = this;
|
||||||
var par = this.getConnectedToTopic();
|
const par = this.getConnectedToTopic();
|
||||||
position = _layoutManager.predict(par.getId(), this._draggedNode.getId(), position, true).position;
|
position = _layoutManager.predict(par.getId(), this._draggedNode.getId(), position, true).position;
|
||||||
}
|
|
||||||
this._position.setValue(position.x, position.y);
|
|
||||||
|
|
||||||
// Elements are positioned in the center.
|
|
||||||
// All topic element must be positioned based on the innerShape.
|
|
||||||
var draggedNode = this._draggedNode;
|
|
||||||
var size = draggedNode.getSize();
|
|
||||||
var cx = position.x - (position.x > 0 ? 0 : size.width);
|
|
||||||
var cy = Math.ceil(position.y - (size.height / 2));
|
|
||||||
this._elem2d.setPosition(cx, cy);
|
|
||||||
|
|
||||||
// In case is not free, pivot must be draw ...
|
|
||||||
if (this.isConnected() && !this.isFreeLayoutOn()) {
|
|
||||||
var parent = this.getConnectedToTopic();
|
|
||||||
var predict = this._layoutManager.predict(parent.getId(), this._draggedNode.getId(), this.getPosition());
|
|
||||||
if (this._order != predict.order) {
|
|
||||||
var dragPivot = this._getDragPivot();
|
|
||||||
var pivotPosition = predict.position;
|
|
||||||
dragPivot.connectTo(parent, pivotPosition);
|
|
||||||
this.setOrder(predict.order);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
updateFreeLayout:function (event) {
|
|
||||||
var isFreeEnabled = (event.metaKey && Browser.Platform.mac) || (event.ctrlKey && !Browser.Platform.mac);
|
|
||||||
if (this.isFreeLayoutOn() != isFreeEnabled) {
|
|
||||||
var dragPivot = this._getDragPivot();
|
|
||||||
dragPivot.setVisibility(!isFreeEnabled);
|
|
||||||
this._isFreeLayoutEnabled = isFreeEnabled;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
setVisibility:function (value) {
|
|
||||||
var dragPivot = this._getDragPivot();
|
|
||||||
dragPivot.setVisibility(value);
|
|
||||||
},
|
|
||||||
|
|
||||||
isVisible:function () {
|
|
||||||
var dragPivot = this._getDragPivot();
|
|
||||||
return dragPivot.isVisible();
|
|
||||||
},
|
|
||||||
|
|
||||||
getInnerShape:function () {
|
|
||||||
return this._elem2d;
|
|
||||||
},
|
|
||||||
|
|
||||||
disconnect:function (workspace) {
|
|
||||||
// Clear connection line ...
|
|
||||||
var dragPivot = this._getDragPivot();
|
|
||||||
dragPivot.disconnect(workspace);
|
|
||||||
},
|
|
||||||
|
|
||||||
connectTo:function (parent) {
|
|
||||||
$assert(parent, 'Parent connection node can not be null.');
|
|
||||||
|
|
||||||
// Where it should be connected ?
|
|
||||||
var predict = designer._eventBussDispatcher._layoutManager.predict(parent.getId(), this._draggedNode.getId(), this.getPosition());
|
|
||||||
|
|
||||||
// Connect pivot ...
|
|
||||||
var dragPivot = this._getDragPivot();
|
|
||||||
var position = predict.position;
|
|
||||||
dragPivot.connectTo(parent, position);
|
|
||||||
dragPivot.setVisibility(true);
|
|
||||||
|
|
||||||
this.setOrder(predict.order);
|
|
||||||
},
|
|
||||||
|
|
||||||
getDraggedTopic:function () {
|
|
||||||
return this._draggedNode;
|
|
||||||
},
|
|
||||||
|
|
||||||
removeFromWorkspace:function (workspace) {
|
|
||||||
if (this._isInWorkspace) {
|
|
||||||
// Remove drag shadow.
|
|
||||||
workspace.removeChild(this._elem2d);
|
|
||||||
|
|
||||||
// Remove pivot shape. To improve performance it will not be removed. Only the visibility will be changed.
|
|
||||||
var dragPivot = this._getDragPivot();
|
|
||||||
dragPivot.setVisibility(false);
|
|
||||||
|
|
||||||
this._isInWorkspace = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
isInWorkspace:function () {
|
|
||||||
return this._isInWorkspace;
|
|
||||||
},
|
|
||||||
|
|
||||||
addToWorkspace:function (workspace) {
|
|
||||||
if (!this._isInWorkspace) {
|
|
||||||
workspace.append(this._elem2d);
|
|
||||||
var dragPivot = this._getDragPivot();
|
|
||||||
dragPivot.addToWorkspace(workspace);
|
|
||||||
this._isInWorkspace = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_getDragPivot:function () {
|
|
||||||
return DragTopic.__getDragPivot();
|
|
||||||
},
|
|
||||||
|
|
||||||
getPosition:function () {
|
|
||||||
return this._position;
|
|
||||||
},
|
|
||||||
|
|
||||||
isDragTopic:function () {
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
applyChanges:function (workspace) {
|
|
||||||
$assert(workspace, 'workspace can not be null');
|
|
||||||
|
|
||||||
|
|
||||||
var actionDispatcher = ActionDispatcher.getInstance();
|
|
||||||
var draggedTopic = this.getDraggedTopic();
|
|
||||||
var topicId = draggedTopic.getId();
|
|
||||||
var position = this.getPosition();
|
|
||||||
|
|
||||||
if (!this.isFreeLayoutOn()) {
|
|
||||||
var order = null;
|
|
||||||
var parent = null;
|
|
||||||
var isDragConnected = this.isConnected();
|
|
||||||
if (isDragConnected) {
|
|
||||||
var targetTopic = this.getConnectedToTopic();
|
|
||||||
order = this._order;
|
|
||||||
parent = targetTopic;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the node is not connected, position based on the original drag topic position.
|
|
||||||
actionDispatcher.dragTopic(topicId, position, order, parent);
|
|
||||||
} else {
|
|
||||||
actionDispatcher.moveTopic(topicId, position);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getConnectedToTopic:function () {
|
|
||||||
var dragPivot = this._getDragPivot();
|
|
||||||
return dragPivot.getTargetTopic();
|
|
||||||
},
|
|
||||||
|
|
||||||
isConnected:function () {
|
|
||||||
return this.getConnectedToTopic() != null;
|
|
||||||
},
|
|
||||||
|
|
||||||
isFreeLayoutOn:function () {
|
|
||||||
// return this._isFreeLayoutEnabled;
|
|
||||||
// Disable free layout ...
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
this._position.setValue(position.x, position.y);
|
||||||
|
|
||||||
|
// Elements are positioned in the center.
|
||||||
|
// All topic element must be positioned based on the innerShape.
|
||||||
|
const draggedNode = this._draggedNode;
|
||||||
|
const size = draggedNode.getSize();
|
||||||
|
const cx = position.x - (position.x > 0 ? 0 : size.width);
|
||||||
|
const cy = Math.ceil(position.y - (size.height / 2));
|
||||||
|
this._elem2d.setPosition(cx, cy);
|
||||||
|
|
||||||
|
// In case is not free, pivot must be draw ...
|
||||||
|
if (this.isConnected() && !this.isFreeLayoutOn()) {
|
||||||
|
const parent = this.getConnectedToTopic();
|
||||||
|
const predict = this._layoutManager.predict(parent.getId(), this._draggedNode.getId(), this.getPosition());
|
||||||
|
if (this._order != predict.order) {
|
||||||
|
const dragPivot = this._getDragPivot();
|
||||||
|
const pivotPosition = predict.position;
|
||||||
|
dragPivot.connectTo(parent, pivotPosition);
|
||||||
|
this.setOrder(predict.order);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
updateFreeLayout(event) {
|
||||||
|
const isFreeEnabled = (event.metaKey && Browser.Platform.mac) || (event.ctrlKey && !Browser.Platform.mac);
|
||||||
|
if (this.isFreeLayoutOn() != isFreeEnabled) {
|
||||||
|
const dragPivot = this._getDragPivot();
|
||||||
|
dragPivot.setVisibility(!isFreeEnabled);
|
||||||
|
this._isFreeLayoutEnabled = isFreeEnabled;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setVisibility(value) {
|
||||||
|
const dragPivot = this._getDragPivot();
|
||||||
|
dragPivot.setVisibility(value);
|
||||||
|
},
|
||||||
|
|
||||||
|
isVisible() {
|
||||||
|
const dragPivot = this._getDragPivot();
|
||||||
|
return dragPivot.isVisible();
|
||||||
|
},
|
||||||
|
|
||||||
|
getInnerShape() {
|
||||||
|
return this._elem2d;
|
||||||
|
},
|
||||||
|
|
||||||
|
disconnect(workspace) {
|
||||||
|
// Clear connection line ...
|
||||||
|
const dragPivot = this._getDragPivot();
|
||||||
|
dragPivot.disconnect(workspace);
|
||||||
|
},
|
||||||
|
|
||||||
|
connectTo(parent) {
|
||||||
|
$assert(parent, 'Parent connection node can not be null.');
|
||||||
|
|
||||||
|
// Where it should be connected ?
|
||||||
|
const predict = designer._eventBussDispatcher._layoutManager.predict(parent.getId(), this._draggedNode.getId(), this.getPosition());
|
||||||
|
|
||||||
|
// Connect pivot ...
|
||||||
|
const dragPivot = this._getDragPivot();
|
||||||
|
const { position } = predict;
|
||||||
|
dragPivot.connectTo(parent, position);
|
||||||
|
dragPivot.setVisibility(true);
|
||||||
|
|
||||||
|
this.setOrder(predict.order);
|
||||||
|
},
|
||||||
|
|
||||||
|
getDraggedTopic() {
|
||||||
|
return this._draggedNode;
|
||||||
|
},
|
||||||
|
|
||||||
|
removeFromWorkspace(workspace) {
|
||||||
|
if (this._isInWorkspace) {
|
||||||
|
// Remove drag shadow.
|
||||||
|
workspace.removeChild(this._elem2d);
|
||||||
|
|
||||||
|
// Remove pivot shape. To improve performance it will not be removed. Only the visibility will be changed.
|
||||||
|
const dragPivot = this._getDragPivot();
|
||||||
|
dragPivot.setVisibility(false);
|
||||||
|
|
||||||
|
this._isInWorkspace = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
isInWorkspace() {
|
||||||
|
return this._isInWorkspace;
|
||||||
|
},
|
||||||
|
|
||||||
|
addToWorkspace(workspace) {
|
||||||
|
if (!this._isInWorkspace) {
|
||||||
|
workspace.append(this._elem2d);
|
||||||
|
const dragPivot = this._getDragPivot();
|
||||||
|
dragPivot.addToWorkspace(workspace);
|
||||||
|
this._isInWorkspace = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_getDragPivot() {
|
||||||
|
return DragTopic.__getDragPivot();
|
||||||
|
},
|
||||||
|
|
||||||
|
getPosition() {
|
||||||
|
return this._position;
|
||||||
|
},
|
||||||
|
|
||||||
|
isDragTopic() {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
applyChanges(workspace) {
|
||||||
|
$assert(workspace, 'workspace can not be null');
|
||||||
|
|
||||||
|
const actionDispatcher = ActionDispatcher.getInstance();
|
||||||
|
const draggedTopic = this.getDraggedTopic();
|
||||||
|
const topicId = draggedTopic.getId();
|
||||||
|
const position = this.getPosition();
|
||||||
|
|
||||||
|
if (!this.isFreeLayoutOn()) {
|
||||||
|
let order = null;
|
||||||
|
let parent = null;
|
||||||
|
const isDragConnected = this.isConnected();
|
||||||
|
if (isDragConnected) {
|
||||||
|
const targetTopic = this.getConnectedToTopic();
|
||||||
|
order = this._order;
|
||||||
|
parent = targetTopic;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the node is not connected, position based on the original drag topic position.
|
||||||
|
actionDispatcher.dragTopic(topicId, position, order, parent);
|
||||||
|
} else {
|
||||||
|
actionDispatcher.moveTopic(topicId, position);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getConnectedToTopic() {
|
||||||
|
const dragPivot = this._getDragPivot();
|
||||||
|
return dragPivot.getTargetTopic();
|
||||||
|
},
|
||||||
|
|
||||||
|
isConnected() {
|
||||||
|
return this.getConnectedToTopic() != null;
|
||||||
|
},
|
||||||
|
|
||||||
|
isFreeLayoutOn() {
|
||||||
|
// return this._isFreeLayoutEnabled;
|
||||||
|
// Disable free layout ...
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
DragTopic.PIVOT_SIZE = {width:50, height:6};
|
DragTopic.PIVOT_SIZE = { width: 50, height: 6 };
|
||||||
|
|
||||||
DragTopic.init = function (workspace) {
|
DragTopic.init = function (workspace) {
|
||||||
|
$assert(workspace, 'workspace can not be null');
|
||||||
$assert(workspace, "workspace can not be null");
|
const pivot = DragTopic.__getDragPivot();
|
||||||
var pivot = DragTopic.__getDragPivot();
|
workspace.append(pivot);
|
||||||
workspace.append(pivot);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
DragTopic.__getDragPivot = function () {
|
DragTopic.__getDragPivot = function () {
|
||||||
var result = DragTopic._dragPivot;
|
let result = DragTopic._dragPivot;
|
||||||
if (!$defined(result)) {
|
if (!$defined(result)) {
|
||||||
result = new DragPivot();
|
result = new DragPivot();
|
||||||
DragTopic._dragPivot = result;
|
DragTopic._dragPivot = result;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DragTopic;
|
export default DragTopic;
|
||||||
|
@ -16,11 +16,10 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const EditorOptions =
|
const EditorOptions = {
|
||||||
{
|
LayoutManager: 'OriginalLayout',
|
||||||
LayoutManager:"OriginalLayout",
|
// LayoutManager:"FreeMindLayout",
|
||||||
// LayoutManager:"FreeMindLayout",
|
textEditor: 'TextEditor',
|
||||||
textEditor:"TextEditor"
|
|
||||||
// textEditor:"RichTextEditor"
|
// textEditor:"RichTextEditor"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,22 +17,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const EditorProperties = new Class({
|
const EditorProperties = new Class({
|
||||||
initialize: function () {
|
initialize() {
|
||||||
this._zoom = 0;
|
this._zoom = 0;
|
||||||
this._position = 0;
|
this._position = 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
setZoom: function (zoom) {
|
setZoom(zoom) {
|
||||||
this._zoom = zoom;
|
this._zoom = zoom;
|
||||||
},
|
},
|
||||||
|
|
||||||
getZoom: function () {
|
getZoom() {
|
||||||
return this._zoom;
|
return this._zoom;
|
||||||
},
|
},
|
||||||
|
|
||||||
asProperties: function () {
|
asProperties() {
|
||||||
return "zoom=" + this._zoom + "\n";
|
return `zoom=${this._zoom}\n`;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default EditorProperties;
|
export default EditorProperties;
|
||||||
|
@ -1,45 +1,43 @@
|
|||||||
const Events = new Class({
|
const Events = new Class({
|
||||||
$events: {},
|
$events: {},
|
||||||
|
|
||||||
_removeOn: function (string) {
|
_removeOn(string) {
|
||||||
return string.replace(/^on([A-Z])/, function (full, first) {
|
return string.replace(/^on([A-Z])/, (full, first) => first.toLowerCase());
|
||||||
return first.toLowerCase();
|
},
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
addEvent: function (type, fn, internal) {
|
addEvent(type, fn, internal) {
|
||||||
type = this._removeOn(type);
|
type = this._removeOn(type);
|
||||||
|
|
||||||
this.$events[type] = (this.$events[type] || []).include(fn);
|
this.$events[type] = (this.$events[type] || []).include(fn);
|
||||||
if (internal) fn.internal = true;
|
if (internal) fn.internal = true;
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
fireEvent: function (type, args, delay) {
|
fireEvent(type, args, delay) {
|
||||||
type = this._removeOn(type);
|
type = this._removeOn(type);
|
||||||
var events = this.$events[type];
|
const events = this.$events[type];
|
||||||
if (!events) return this;
|
if (!events) return this;
|
||||||
args = Array.isArray(args) ? args : [args];
|
args = Array.isArray(args) ? args : [args];
|
||||||
_.each(
|
_.each(
|
||||||
events,
|
events,
|
||||||
function (fn) {
|
function (fn) {
|
||||||
if (delay) fn.delay(delay, this, args);
|
if (delay) fn.delay(delay, this, args);
|
||||||
else fn.apply(this, args);
|
else fn.apply(this, args);
|
||||||
},
|
},
|
||||||
this
|
this,
|
||||||
);
|
);
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
removeEvent: function (type, fn) {
|
removeEvent(type, fn) {
|
||||||
type = this._removeOn(type);
|
type = this._removeOn(type);
|
||||||
var events = this.$events[type];
|
const events = this.$events[type];
|
||||||
if (events && !fn.internal) {
|
if (events && !fn.internal) {
|
||||||
var index = events.indexOf(fn);
|
const index = events.indexOf(fn);
|
||||||
if (index != -1) events.splice(index, 1);
|
if (index != -1) events.splice(index, 1);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default Events;
|
export default Events;
|
||||||
|
@ -15,44 +15,45 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
const web2D = require('@wismapping/web2d')
|
const web2D = require('@wismapping/web2d');
|
||||||
const web2d = web2D()
|
|
||||||
|
const web2d = web2D();
|
||||||
|
|
||||||
const Icon = new Class({
|
const Icon = new Class({
|
||||||
initialize: function (url) {
|
initialize(url) {
|
||||||
$assert(url, 'topic can not be null');
|
$assert(url, 'topic can not be null');
|
||||||
this._image = new web2d.Image();
|
this._image = new web2d.Image();
|
||||||
this._image.setHref(url);
|
this._image.setHref(url);
|
||||||
this._image.setSize(Icon.SIZE, Icon.SIZE);
|
this._image.setSize(Icon.SIZE, Icon.SIZE);
|
||||||
},
|
},
|
||||||
|
|
||||||
getImage: function () {
|
getImage() {
|
||||||
return this._image;
|
return this._image;
|
||||||
},
|
},
|
||||||
|
|
||||||
setGroup: function (group) {
|
setGroup(group) {
|
||||||
this._group = group;
|
this._group = group;
|
||||||
},
|
},
|
||||||
|
|
||||||
getGroup: function () {
|
getGroup() {
|
||||||
return this._group;
|
return this._group;
|
||||||
},
|
},
|
||||||
|
|
||||||
getSize: function () {
|
getSize() {
|
||||||
return this._image.getSize();
|
return this._image.getSize();
|
||||||
},
|
},
|
||||||
|
|
||||||
getPosition: function () {
|
getPosition() {
|
||||||
return this._image.getPosition();
|
return this._image.getPosition();
|
||||||
},
|
},
|
||||||
|
|
||||||
addEvent: function (type, fnc) {
|
addEvent(type, fnc) {
|
||||||
this._image.addEvent(type, fnc);
|
this._image.addEvent(type, fnc);
|
||||||
},
|
},
|
||||||
|
|
||||||
remove: function () {
|
remove() {
|
||||||
throw "Unsupported operation";
|
throw 'Unsupported operation';
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Icon.SIZE = 90;
|
Icon.SIZE = 90;
|
||||||
|
@ -15,157 +15,154 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
const web2D = require('@wismapping/web2d')
|
const web2D = require('@wismapping/web2d');
|
||||||
|
|
||||||
const web2d = web2D();
|
const web2d = web2D();
|
||||||
const Icon = require('./Icon');
|
const Icon = require('./Icon');
|
||||||
|
|
||||||
const IconGroup = new Class(/**@lends IconGroup */{
|
const IconGroup = new Class(/** @lends IconGroup */{
|
||||||
/**
|
/**
|
||||||
* @constructs
|
* @constructs
|
||||||
* @param topicId
|
* @param topicId
|
||||||
* @param iconSize
|
* @param iconSize
|
||||||
* @throws will throw an error if topicId is null or undefined
|
* @throws will throw an error if topicId is null or undefined
|
||||||
* @throws will throw an error if iconSize is null or undefined
|
* @throws will throw an error if iconSize is null or undefined
|
||||||
*/
|
*/
|
||||||
initialize: function (topicId, iconSize) {
|
initialize(topicId, iconSize) {
|
||||||
$assert($defined(topicId), "topicId can not be null");
|
$assert($defined(topicId), 'topicId can not be null');
|
||||||
$assert($defined(iconSize), "iconSize can not be null");
|
$assert($defined(iconSize), 'iconSize can not be null');
|
||||||
|
|
||||||
this._icons = [];
|
this._icons = [];
|
||||||
this._group = new web2d.Group({
|
this._group = new web2d.Group({
|
||||||
width: 0,
|
width: 0,
|
||||||
height: iconSize,
|
height: iconSize,
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
coordSizeWidth: 0,
|
coordSizeWidth: 0,
|
||||||
coordSizeHeight: 100
|
coordSizeHeight: 100,
|
||||||
});
|
});
|
||||||
this._removeTip = new IconGroup.RemoveTip(this._group, topicId);
|
this._removeTip = new IconGroup.RemoveTip(this._group, topicId);
|
||||||
this.seIconSize(iconSize, iconSize);
|
this.seIconSize(iconSize, iconSize);
|
||||||
|
|
||||||
this._registerListeners();
|
this._registerListeners();
|
||||||
|
},
|
||||||
|
|
||||||
},
|
/** */
|
||||||
|
setPosition(x, y) {
|
||||||
|
this._group.setPosition(x, y);
|
||||||
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setPosition: function (x, y) {
|
getPosition() {
|
||||||
this._group.setPosition(x, y);
|
return this._group.getPosition();
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getPosition: function () {
|
getNativeElement() {
|
||||||
return this._group.getPosition();
|
return this._group;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getNativeElement: function () {
|
getSize() {
|
||||||
return this._group;
|
return this._group.getSize();
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getSize: function () {
|
seIconSize(width, height) {
|
||||||
return this._group.getSize();
|
this._iconSize = { width, height };
|
||||||
},
|
this._resize(this._icons.length);
|
||||||
|
},
|
||||||
|
|
||||||
/** */
|
/**
|
||||||
seIconSize: function (width, height) {
|
|
||||||
this._iconSize = {width: width, height: height};
|
|
||||||
this._resize(this._icons.length);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param icon the icon to be added to the icon group
|
* @param icon the icon to be added to the icon group
|
||||||
* @param {Boolean} remove
|
* @param {Boolean} remove
|
||||||
* @throws will throw an error if icon is not defined
|
* @throws will throw an error if icon is not defined
|
||||||
*/
|
*/
|
||||||
addIcon: function (icon, remove) {
|
addIcon(icon, remove) {
|
||||||
$defined(icon, "icon is not defined");
|
$defined(icon, 'icon is not defined');
|
||||||
|
|
||||||
icon.setGroup(this);
|
icon.setGroup(this);
|
||||||
this._icons.push(icon);
|
this._icons.push(icon);
|
||||||
|
|
||||||
// Adjust group and position ...
|
// Adjust group and position ...
|
||||||
this._resize(this._icons.length);
|
this._resize(this._icons.length);
|
||||||
this._positionIcon(icon, this._icons.length - 1);
|
this._positionIcon(icon, this._icons.length - 1);
|
||||||
|
|
||||||
var imageShape = icon.getImage();
|
const imageShape = icon.getImage();
|
||||||
this._group.append(imageShape);
|
this._group.append(imageShape);
|
||||||
|
|
||||||
// Register event for the group ..
|
// Register event for the group ..
|
||||||
if (remove) {
|
if (remove) {
|
||||||
this._removeTip.decorate(this._topicId, icon);
|
this._removeTip.decorate(this._topicId, icon);
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_findIconFromModel: function (iconModel) {
|
|
||||||
var result = null;
|
|
||||||
_.each(this._icons, function (icon) {
|
|
||||||
var elModel = icon.getModel();
|
|
||||||
if (elModel.getId() == iconModel.getId()) {
|
|
||||||
result = icon;
|
|
||||||
}
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
if (result == null) {
|
|
||||||
throw new Error("Icon can no be found:" + iconModel.getId() + ", Icons:" + this._icons);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
/** */
|
|
||||||
removeIconByModel: function (featureModel) {
|
|
||||||
$assert(featureModel, "featureModel can not be null");
|
|
||||||
|
|
||||||
var icon = this._findIconFromModel(featureModel);
|
|
||||||
this._removeIcon(icon);
|
|
||||||
},
|
|
||||||
|
|
||||||
_removeIcon: function (icon) {
|
|
||||||
$assert(icon, "icon can not be null");
|
|
||||||
|
|
||||||
this._removeTip.close(0);
|
|
||||||
this._group.removeChild(icon.getImage());
|
|
||||||
|
|
||||||
this._icons.erase(icon);
|
|
||||||
this._resize(this._icons.length);
|
|
||||||
var me = this;
|
|
||||||
// Add all again ...
|
|
||||||
_.each(this._icons, function (elem, i) {
|
|
||||||
me._positionIcon(elem, i);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/** */
|
|
||||||
moveToFront: function () {
|
|
||||||
this._group.moveToFront();
|
|
||||||
},
|
|
||||||
|
|
||||||
_registerListeners: function () {
|
|
||||||
this._group.addEvent('click', function (event) {
|
|
||||||
// Avoid node creation ...
|
|
||||||
event.stopPropagation();
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
this._group.addEvent('dblclick', function (event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
_resize: function (iconsLength) {
|
|
||||||
this._group.setSize(iconsLength * this._iconSize.width, this._iconSize.height);
|
|
||||||
|
|
||||||
var iconSize = Icon.SIZE + (IconGroup.ICON_PADDING * 2);
|
|
||||||
this._group.setCoordSize(iconsLength * iconSize, iconSize);
|
|
||||||
},
|
|
||||||
|
|
||||||
_positionIcon: function (icon, order) {
|
|
||||||
|
|
||||||
var iconSize = Icon.SIZE + (IconGroup.ICON_PADDING * 2);
|
|
||||||
icon.getImage().setPosition(iconSize * order + IconGroup.ICON_PADDING, IconGroup.ICON_PADDING);
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_findIconFromModel(iconModel) {
|
||||||
|
let result = null;
|
||||||
|
_.each(this._icons, (icon) => {
|
||||||
|
const elModel = icon.getModel();
|
||||||
|
if (elModel.getId() == iconModel.getId()) {
|
||||||
|
result = icon;
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
if (result == null) {
|
||||||
|
throw new Error(`Icon can no be found:${iconModel.getId()}, Icons:${this._icons}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
/** */
|
||||||
|
removeIconByModel(featureModel) {
|
||||||
|
$assert(featureModel, 'featureModel can not be null');
|
||||||
|
|
||||||
|
const icon = this._findIconFromModel(featureModel);
|
||||||
|
this._removeIcon(icon);
|
||||||
|
},
|
||||||
|
|
||||||
|
_removeIcon(icon) {
|
||||||
|
$assert(icon, 'icon can not be null');
|
||||||
|
|
||||||
|
this._removeTip.close(0);
|
||||||
|
this._group.removeChild(icon.getImage());
|
||||||
|
|
||||||
|
this._icons.erase(icon);
|
||||||
|
this._resize(this._icons.length);
|
||||||
|
const me = this;
|
||||||
|
// Add all again ...
|
||||||
|
_.each(this._icons, (elem, i) => {
|
||||||
|
me._positionIcon(elem, i);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/** */
|
||||||
|
moveToFront() {
|
||||||
|
this._group.moveToFront();
|
||||||
|
},
|
||||||
|
|
||||||
|
_registerListeners() {
|
||||||
|
this._group.addEvent('click', (event) => {
|
||||||
|
// Avoid node creation ...
|
||||||
|
event.stopPropagation();
|
||||||
|
});
|
||||||
|
|
||||||
|
this._group.addEvent('dblclick', (event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_resize(iconsLength) {
|
||||||
|
this._group.setSize(iconsLength * this._iconSize.width, this._iconSize.height);
|
||||||
|
|
||||||
|
const iconSize = Icon.SIZE + (IconGroup.ICON_PADDING * 2);
|
||||||
|
this._group.setCoordSize(iconsLength * iconSize, iconSize);
|
||||||
|
},
|
||||||
|
|
||||||
|
_positionIcon(icon, order) {
|
||||||
|
const iconSize = Icon.SIZE + (IconGroup.ICON_PADDING * 2);
|
||||||
|
icon.getImage().setPosition(iconSize * order + IconGroup.ICON_PADDING, IconGroup.ICON_PADDING);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -176,169 +173,164 @@ const IconGroup = new Class(/**@lends IconGroup */{
|
|||||||
IconGroup.ICON_PADDING = 5;
|
IconGroup.ICON_PADDING = 5;
|
||||||
|
|
||||||
IconGroup.RemoveTip = new Class(/** @lends IconGroup.RemoveTip */{
|
IconGroup.RemoveTip = new Class(/** @lends IconGroup.RemoveTip */{
|
||||||
/**
|
/**
|
||||||
* @classdesc inner class of IconGroup
|
* @classdesc inner class of IconGroup
|
||||||
* @constructs
|
* @constructs
|
||||||
* @param container
|
* @param container
|
||||||
*/
|
*/
|
||||||
initialize: function (container) {
|
initialize(container) {
|
||||||
$assert(container, "group can not be null");
|
$assert(container, 'group can not be null');
|
||||||
this._fadeElem = container;
|
this._fadeElem = container;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
/**
|
|
||||||
* @param topicId
|
* @param topicId
|
||||||
* @param icon
|
* @param icon
|
||||||
* @throws will throw an error if icon is null or undefined
|
* @throws will throw an error if icon is null or undefined
|
||||||
*/
|
*/
|
||||||
show: function (topicId, icon) {
|
show(topicId, icon) {
|
||||||
$assert(icon, 'icon can not be null');
|
$assert(icon, 'icon can not be null');
|
||||||
|
|
||||||
// Nothing to do ...
|
// Nothing to do ...
|
||||||
if (this._activeIcon != icon) {
|
if (this._activeIcon != icon) {
|
||||||
// If there is an active icon, close it first ...
|
// If there is an active icon, close it first ...
|
||||||
if (this._activeIcon) {
|
if (this._activeIcon) {
|
||||||
this.close(0);
|
this.close(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now, let move the position the icon...
|
// Now, let move the position the icon...
|
||||||
var pos = icon.getPosition();
|
const pos = icon.getPosition();
|
||||||
|
|
||||||
// Register events ...
|
// Register events ...
|
||||||
var widget = this._buildWeb2d();
|
const widget = this._buildWeb2d();
|
||||||
widget.addEvent('click', function () {
|
widget.addEvent('click', () => {
|
||||||
icon.remove();
|
icon.remove();
|
||||||
});
|
});
|
||||||
|
|
||||||
var me = this;
|
const me = this;
|
||||||
|
|
||||||
widget.addEvent('mouseover', function () {
|
widget.addEvent('mouseover', () => {
|
||||||
me.show(topicId, icon);
|
me.show(topicId, icon);
|
||||||
});
|
});
|
||||||
|
|
||||||
widget.addEvent('mouseout', function () {
|
widget.addEvent('mouseout', () => {
|
||||||
me.hide();
|
me.hide();
|
||||||
});
|
});
|
||||||
|
|
||||||
widget.setPosition(pos.x + 80, pos.y - 50);
|
widget.setPosition(pos.x + 80, pos.y - 50);
|
||||||
this._fadeElem.append(widget);
|
this._fadeElem.append(widget);
|
||||||
|
|
||||||
// Setup current element ...
|
// Setup current element ...
|
||||||
this._activeIcon = icon;
|
this._activeIcon = icon;
|
||||||
this._widget = widget;
|
this._widget = widget;
|
||||||
|
} else {
|
||||||
|
clearTimeout(this._closeTimeoutId);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
} else {
|
/** */
|
||||||
clearTimeout(this._closeTimeoutId);
|
hide() {
|
||||||
}
|
this.close(200);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/**
|
||||||
hide: function () {
|
|
||||||
this.close(200);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param delay
|
* @param delay
|
||||||
*/
|
*/
|
||||||
close: function (delay) {
|
close(delay) {
|
||||||
|
// This is not ok, trying to close the same dialog twice ?
|
||||||
|
if (this._closeTimeoutId) {
|
||||||
|
clearTimeout(this._closeTimeoutId);
|
||||||
|
}
|
||||||
|
|
||||||
// This is not ok, trying to close the same dialog twice ?
|
const me = this;
|
||||||
if (this._closeTimeoutId) {
|
if (this._activeIcon) {
|
||||||
clearTimeout(this._closeTimeoutId)
|
const widget = this._widget;
|
||||||
}
|
const close = function () {
|
||||||
|
me._activeIcon = null;
|
||||||
|
me._fadeElem.removeChild(widget);
|
||||||
|
me._widget = null;
|
||||||
|
me._closeTimeoutId = null;
|
||||||
|
};
|
||||||
|
|
||||||
var me = this;
|
if (!$defined(delay) || delay == 0) {
|
||||||
if (this._activeIcon) {
|
close();
|
||||||
var widget = this._widget;
|
} else {
|
||||||
var close = function () {
|
this._closeTimeoutId = close.delay(delay);
|
||||||
me._activeIcon = null;
|
}
|
||||||
me._fadeElem.removeChild(widget);
|
}
|
||||||
me._widget = null;
|
},
|
||||||
me._closeTimeoutId = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!$defined(delay) || delay == 0) {
|
_buildWeb2d() {
|
||||||
close();
|
const result = new web2d.Group({
|
||||||
}
|
width: 10,
|
||||||
else {
|
height: 10,
|
||||||
this._closeTimeoutId = close.delay(delay);
|
x: 0,
|
||||||
}
|
y: 0,
|
||||||
}
|
coordSizeWidth: 10,
|
||||||
},
|
coordSizeHeight: 10,
|
||||||
|
});
|
||||||
|
|
||||||
_buildWeb2d: function () {
|
const outerRect = new web2d.Rect(0, {
|
||||||
var result = new web2d.Group({
|
x: 0,
|
||||||
width: 10,
|
y: 0,
|
||||||
height: 10,
|
width: 10,
|
||||||
x: 0,
|
height: 10,
|
||||||
y: 0,
|
stroke: '0',
|
||||||
coordSizeWidth: 10,
|
fillColor: 'black',
|
||||||
coordSizeHeight: 10
|
});
|
||||||
});
|
result.append(outerRect);
|
||||||
|
outerRect.setCursor('pointer');
|
||||||
|
|
||||||
var outerRect = new web2d.Rect(0, {
|
const innerRect = new web2d.Rect(0, {
|
||||||
x: 0,
|
x: 1,
|
||||||
y: 0,
|
y: 1,
|
||||||
width: 10,
|
width: 8,
|
||||||
height: 10,
|
height: 8,
|
||||||
stroke: '0',
|
stroke: '1 solid white',
|
||||||
fillColor: 'black'
|
fillColor: 'gray',
|
||||||
});
|
});
|
||||||
result.append(outerRect);
|
result.append(innerRect);
|
||||||
outerRect.setCursor('pointer');
|
|
||||||
|
|
||||||
var innerRect = new web2d.Rect(0, {
|
const line = new web2d.Line({ stroke: '1 solid white' });
|
||||||
x: 1,
|
line.setFrom(1, 1);
|
||||||
y: 1,
|
line.setTo(9, 9);
|
||||||
width: 8,
|
result.append(line);
|
||||||
height: 8,
|
|
||||||
stroke: '1 solid white',
|
|
||||||
fillColor: 'gray'
|
|
||||||
});
|
|
||||||
result.append(innerRect);
|
|
||||||
|
|
||||||
var line = new web2d.Line({stroke: '1 solid white'});
|
const line2 = new web2d.Line({ stroke: '1 solid white' });
|
||||||
line.setFrom(1, 1);
|
line2.setFrom(1, 9);
|
||||||
line.setTo(9, 9);
|
line2.setTo(9, 1);
|
||||||
result.append(line);
|
result.append(line2);
|
||||||
|
|
||||||
var line2 = new web2d.Line({stroke: '1 solid white'});
|
// Some events ...
|
||||||
line2.setFrom(1, 9);
|
result.addEvent('mouseover', () => {
|
||||||
line2.setTo(9, 1);
|
innerRect.setFill('#CC0033');
|
||||||
result.append(line2);
|
});
|
||||||
|
result.addEvent('mouseout', () => {
|
||||||
|
innerRect.setFill('gray');
|
||||||
|
});
|
||||||
|
|
||||||
// Some events ...
|
result.setSize(50, 50);
|
||||||
result.addEvent('mouseover', function () {
|
return result;
|
||||||
innerRect.setFill('#CC0033');
|
},
|
||||||
});
|
|
||||||
result.addEvent('mouseout', function () {
|
|
||||||
innerRect.setFill('gray');
|
|
||||||
});
|
|
||||||
|
|
||||||
result.setSize(50, 50);
|
/**
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param topicId
|
* @param topicId
|
||||||
* @param icon
|
* @param icon
|
||||||
*/
|
*/
|
||||||
decorate: function (topicId, icon) {
|
decorate(topicId, icon) {
|
||||||
|
const me = this;
|
||||||
|
|
||||||
var me = this;
|
if (!icon.__remove) {
|
||||||
|
icon.addEvent('mouseover', () => {
|
||||||
|
me.show(topicId, icon);
|
||||||
|
});
|
||||||
|
|
||||||
if (!icon.__remove) {
|
icon.addEvent('mouseout', () => {
|
||||||
icon.addEvent('mouseover', function () {
|
me.hide();
|
||||||
me.show(topicId, icon);
|
});
|
||||||
});
|
icon.__remove = true;
|
||||||
|
|
||||||
icon.addEvent('mouseout', function () {
|
|
||||||
me.hide();
|
|
||||||
});
|
|
||||||
icon.__remove = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -19,148 +19,144 @@ const Icon = require('./Icon').default;
|
|||||||
const ActionDispatcher = require('./ActionDispatcher').default;
|
const ActionDispatcher = require('./ActionDispatcher').default;
|
||||||
|
|
||||||
const ImageIcon = new Class({
|
const ImageIcon = new Class({
|
||||||
Extends: Icon,
|
Extends: Icon,
|
||||||
initialize: function (topic, iconModel, readOnly) {
|
initialize(topic, iconModel, readOnly) {
|
||||||
$assert(iconModel, 'iconModel can not be null');
|
$assert(iconModel, 'iconModel can not be null');
|
||||||
$assert(topic, 'topic can not be null');
|
$assert(topic, 'topic can not be null');
|
||||||
|
|
||||||
this._topicId = topic.getId();
|
this._topicId = topic.getId();
|
||||||
this._featureModel = iconModel;
|
this._featureModel = iconModel;
|
||||||
|
|
||||||
// Build graph image representation ...
|
// Build graph image representation ...
|
||||||
var iconType = iconModel.getIconType();
|
const iconType = iconModel.getIconType();
|
||||||
var imgUrl = this._getImageUrl(iconType);
|
const imgUrl = this._getImageUrl(iconType);
|
||||||
this.parent(imgUrl);
|
this.parent(imgUrl);
|
||||||
|
|
||||||
if (!readOnly) {
|
if (!readOnly) {
|
||||||
|
// Icon
|
||||||
|
const image = this.getImage();
|
||||||
|
const me = this;
|
||||||
|
image.addEvent('click', () => {
|
||||||
|
const iconType = iconModel.getIconType();
|
||||||
|
const newIconType = me._getNextFamilyIconId(iconType);
|
||||||
|
iconModel.setIconType(newIconType);
|
||||||
|
|
||||||
//Icon
|
const imgUrl = me._getImageUrl(newIconType);
|
||||||
var image = this.getImage();
|
me._image.setHref(imgUrl);
|
||||||
var me = this;
|
});
|
||||||
image.addEvent('click', function () {
|
this._image.setCursor('pointer');
|
||||||
|
|
||||||
var iconType = iconModel.getIconType();
|
|
||||||
var newIconType = me._getNextFamilyIconId(iconType);
|
|
||||||
iconModel.setIconType(newIconType);
|
|
||||||
|
|
||||||
var imgUrl = me._getImageUrl(newIconType);
|
|
||||||
me._image.setHref(imgUrl);
|
|
||||||
|
|
||||||
});
|
|
||||||
this._image.setCursor('pointer');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_getImageUrl: function (iconId) {
|
|
||||||
return "icons/" + iconId + ".png";
|
|
||||||
},
|
|
||||||
|
|
||||||
getModel: function () {
|
|
||||||
return this._featureModel;
|
|
||||||
},
|
|
||||||
|
|
||||||
_getNextFamilyIconId: function (iconId) {
|
|
||||||
|
|
||||||
var familyIcons = this._getFamilyIcons(iconId);
|
|
||||||
$assert(familyIcons != null, "Family Icon not found!");
|
|
||||||
|
|
||||||
var result = null;
|
|
||||||
for (var i = 0; i < familyIcons.length && result == null; i++) {
|
|
||||||
if (familyIcons[i] == iconId) {
|
|
||||||
//Is last one?
|
|
||||||
if (i == (familyIcons.length - 1)) {
|
|
||||||
result = familyIcons[0];
|
|
||||||
} else {
|
|
||||||
result = familyIcons[i + 1];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
_getFamilyIcons: function (iconId) {
|
|
||||||
$assert(iconId != null, "id must not be null");
|
|
||||||
$assert(iconId.indexOf("_") != -1, "Invalid icon id (it must contain '_')");
|
|
||||||
|
|
||||||
var result = null;
|
|
||||||
for (var i = 0; i < ImageIcon.prototype.ICON_FAMILIES.length; i++) {
|
|
||||||
var family = ImageIcon.prototype.ICON_FAMILIES[i];
|
|
||||||
var iconFamilyId = iconId.substr(0, iconId.indexOf("_"));
|
|
||||||
|
|
||||||
if (family.id == iconFamilyId) {
|
|
||||||
result = family.icons;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
remove: function () {
|
|
||||||
var actionDispatcher = ActionDispatcher.getInstance();
|
|
||||||
var featureId = this._featureModel.getId();
|
|
||||||
var topicId = this._topicId;
|
|
||||||
actionDispatcher.removeFeatureFromTopic(topicId, featureId);
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_getImageUrl(iconId) {
|
||||||
|
return `icons/${iconId}.png`;
|
||||||
|
},
|
||||||
|
|
||||||
|
getModel() {
|
||||||
|
return this._featureModel;
|
||||||
|
},
|
||||||
|
|
||||||
|
_getNextFamilyIconId(iconId) {
|
||||||
|
const familyIcons = this._getFamilyIcons(iconId);
|
||||||
|
$assert(familyIcons != null, 'Family Icon not found!');
|
||||||
|
|
||||||
|
let result = null;
|
||||||
|
for (let i = 0; i < familyIcons.length && result == null; i++) {
|
||||||
|
if (familyIcons[i] == iconId) {
|
||||||
|
// Is last one?
|
||||||
|
if (i == (familyIcons.length - 1)) {
|
||||||
|
result = familyIcons[0];
|
||||||
|
} else {
|
||||||
|
result = familyIcons[i + 1];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
_getFamilyIcons(iconId) {
|
||||||
|
$assert(iconId != null, 'id must not be null');
|
||||||
|
$assert(iconId.indexOf('_') != -1, "Invalid icon id (it must contain '_')");
|
||||||
|
|
||||||
|
let result = null;
|
||||||
|
for (let i = 0; i < ImageIcon.prototype.ICON_FAMILIES.length; i++) {
|
||||||
|
const family = ImageIcon.prototype.ICON_FAMILIES[i];
|
||||||
|
const iconFamilyId = iconId.substr(0, iconId.indexOf('_'));
|
||||||
|
|
||||||
|
if (family.id == iconFamilyId) {
|
||||||
|
result = family.icons;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
remove() {
|
||||||
|
const actionDispatcher = ActionDispatcher.getInstance();
|
||||||
|
const featureId = this._featureModel.getId();
|
||||||
|
const topicId = this._topicId;
|
||||||
|
actionDispatcher.removeFeatureFromTopic(topicId, featureId);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
ImageIcon.prototype.ICON_FAMILIES = [
|
ImageIcon.prototype.ICON_FAMILIES = [
|
||||||
{"id": "face", "icons": ["face_plain", "face_sad", "face_crying", "face_smile", "face_surprise", "face_wink"]},
|
{ id: 'face', icons: ['face_plain', 'face_sad', 'face_crying', 'face_smile', 'face_surprise', 'face_wink'] },
|
||||||
{"id": "funy", "icons": ["funy_angel", "funy_devilish", "funy_glasses", "funy_grin", "funy_kiss", "funy_monkey"]},
|
{ id: 'funy', icons: ['funy_angel', 'funy_devilish', 'funy_glasses', 'funy_grin', 'funy_kiss', 'funy_monkey'] },
|
||||||
{"id": "conn", "icons": ["conn_connect", "conn_disconnect"]},
|
{ id: 'conn', icons: ['conn_connect', 'conn_disconnect'] },
|
||||||
{
|
{
|
||||||
"id": "sport",
|
id: 'sport',
|
||||||
"icons": ["sport_basketball", "sport_football", "sport_golf", "sport_raquet", "sport_shuttlecock", "sport_soccer", "sport_tennis"]
|
icons: ['sport_basketball', 'sport_football', 'sport_golf', 'sport_raquet', 'sport_shuttlecock', 'sport_soccer', 'sport_tennis'],
|
||||||
},
|
},
|
||||||
{"id": "bulb", "icons": ["bulb_light_on", "bulb_light_off"]},
|
{ id: 'bulb', icons: ['bulb_light_on', 'bulb_light_off'] },
|
||||||
{"id": "thumb", "icons": ["thumb_thumb_up", "thumb_thumb_down"]},
|
{ id: 'thumb', icons: ['thumb_thumb_up', 'thumb_thumb_down'] },
|
||||||
{"id": "tick", "icons": ["tick_tick", "tick_cross"]},
|
{ id: 'tick', icons: ['tick_tick', 'tick_cross'] },
|
||||||
{
|
{
|
||||||
"id": "onoff",
|
id: 'onoff',
|
||||||
"icons": ["onoff_clock", "onoff_clock_red", "onoff_add", "onoff_delete", "onoff_status_offline", "onoff_status_online"]
|
icons: ['onoff_clock', 'onoff_clock_red', 'onoff_add', 'onoff_delete', 'onoff_status_offline', 'onoff_status_online'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "money",
|
id: 'money',
|
||||||
"icons": ["money_money", "money_dollar", "money_euro", "money_pound", "money_yen", "money_coins", "money_ruby"]
|
icons: ['money_money', 'money_dollar', 'money_euro', 'money_pound', 'money_yen', 'money_coins', 'money_ruby'],
|
||||||
},
|
},
|
||||||
{"id": "time", "icons": ["time_calendar", "time_clock", "time_hourglass"]},
|
{ id: 'time', icons: ['time_calendar', 'time_clock', 'time_hourglass'] },
|
||||||
{
|
{
|
||||||
"id": "number",
|
id: 'number',
|
||||||
"icons": ["number_1", "number_2", "number_3", "number_4", "number_5", "number_6", "number_7", "number_8", "number_9"]
|
icons: ['number_1', 'number_2', 'number_3', 'number_4', 'number_5', 'number_6', 'number_7', 'number_8', 'number_9'],
|
||||||
},
|
},
|
||||||
{"id": "chart", "icons": ["chart_bar", "chart_line", "chart_curve", "chart_pie", "chart_organisation"]},
|
{ id: 'chart', icons: ['chart_bar', 'chart_line', 'chart_curve', 'chart_pie', 'chart_organisation'] },
|
||||||
{"id": "sign", "icons": ["sign_warning", "sign_info", "sign_stop", "sign_help", "sign_cancel"]},
|
{ id: 'sign', icons: ['sign_warning', 'sign_info', 'sign_stop', 'sign_help', 'sign_cancel'] },
|
||||||
{
|
{
|
||||||
"id": "hard",
|
id: 'hard',
|
||||||
"icons": ["hard_cd", "hard_computer", "hard_controller", "hard_driver_disk", "hard_ipod", "hard_keyboard", "hard_mouse", "hard_printer"]
|
icons: ['hard_cd', 'hard_computer', 'hard_controller', 'hard_driver_disk', 'hard_ipod', 'hard_keyboard', 'hard_mouse', 'hard_printer'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "soft",
|
id: 'soft',
|
||||||
"icons": ["soft_bug", "soft_cursor", "soft_database_table", "soft_database", "soft_feed", "soft_folder_explore", "soft_rss", "soft_penguin"]
|
icons: ['soft_bug', 'soft_cursor', 'soft_database_table', 'soft_database', 'soft_feed', 'soft_folder_explore', 'soft_rss', 'soft_penguin'],
|
||||||
},
|
},
|
||||||
{"id": "arrow", "icons": ["arrow_up", "arrow_down", "arrow_left", "arrow_right"]},
|
{ id: 'arrow', icons: ['arrow_up', 'arrow_down', 'arrow_left', 'arrow_right'] },
|
||||||
{
|
{
|
||||||
"id": "arrowc",
|
id: 'arrowc',
|
||||||
"icons": ["arrowc_rotate_anticlockwise", "arrowc_rotate_clockwise", "arrowc_turn_left", "arrowc_turn_right"]
|
icons: ['arrowc_rotate_anticlockwise', 'arrowc_rotate_clockwise', 'arrowc_turn_left', 'arrowc_turn_right'],
|
||||||
},
|
},
|
||||||
{"id": "people", "icons": ["people_group", "people_male1", "people_male2", "people_female1", "people_female2"]},
|
{ id: 'people', icons: ['people_group', 'people_male1', 'people_male2', 'people_female1', 'people_female2'] },
|
||||||
{"id": "mail", "icons": ["mail_envelop", "mail_mailbox", "mail_edit", "mail_list"]},
|
{ id: 'mail', icons: ['mail_envelop', 'mail_mailbox', 'mail_edit', 'mail_list'] },
|
||||||
{"id": "flag", "icons": ["flag_blue", "flag_green", "flag_orange", "flag_pink", "flag_purple", "flag_yellow"]},
|
{ id: 'flag', icons: ['flag_blue', 'flag_green', 'flag_orange', 'flag_pink', 'flag_purple', 'flag_yellow'] },
|
||||||
{
|
{
|
||||||
"id": "bullet",
|
id: 'bullet',
|
||||||
"icons": ["bullet_black", "bullet_blue", "bullet_green", "bullet_orange", "bullet_red", "bullet_pink", "bullet_purple"]
|
icons: ['bullet_black', 'bullet_blue', 'bullet_green', 'bullet_orange', 'bullet_red', 'bullet_pink', 'bullet_purple'],
|
||||||
},
|
},
|
||||||
{"id": "tag", "icons": ["tag_blue", "tag_green", "tag_orange", "tag_red", "tag_pink", "tag_yellow"]},
|
{ id: 'tag', icons: ['tag_blue', 'tag_green', 'tag_orange', 'tag_red', 'tag_pink', 'tag_yellow'] },
|
||||||
{
|
{
|
||||||
"id": "object",
|
id: 'object',
|
||||||
"icons": ["object_bell", "object_clanbomber", "object_key", "object_pencil", "object_phone", "object_magnifier", "object_clip", "object_music", "object_star", "object_wizard", "object_house", "object_cake", "object_camera", "object_palette", "object_rainbow"]
|
icons: ['object_bell', 'object_clanbomber', 'object_key', 'object_pencil', 'object_phone', 'object_magnifier', 'object_clip', 'object_music', 'object_star', 'object_wizard', 'object_house', 'object_cake', 'object_camera', 'object_palette', 'object_rainbow'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "weather",
|
id: 'weather',
|
||||||
"icons": ["weather_clear-night", "weather_clear", "weather_few-clouds-night", "weather_few-clouds", "weather_overcast", "weather_severe-alert", "weather_showers-scattered", "weather_showers", "weather_snow", "weather_storm"]
|
icons: ['weather_clear-night', 'weather_clear', 'weather_few-clouds-night', 'weather_few-clouds', 'weather_overcast', 'weather_severe-alert', 'weather_showers-scattered', 'weather_showers', 'weather_snow', 'weather_storm'],
|
||||||
},
|
},
|
||||||
{"id": "task", "icons": ["task_0", "task_25", "task_50", "task_75", "task_100"]}
|
{ id: 'task', icons: ['task_0', 'task_25', 'task_50', 'task_75', 'task_100'] },
|
||||||
];
|
];
|
||||||
|
|
||||||
export default ImageIcon;
|
export default ImageIcon;
|
||||||
|
@ -18,17 +18,17 @@
|
|||||||
|
|
||||||
const Keyboard = new Class({
|
const Keyboard = new Class({
|
||||||
|
|
||||||
initialize: function () {
|
initialize() {
|
||||||
},
|
},
|
||||||
|
|
||||||
addShortcut: function (shortcuts, callback) {
|
addShortcut(shortcuts, callback) {
|
||||||
if (!$.isArray(shortcuts)) {
|
if (!$.isArray(shortcuts)) {
|
||||||
shortcuts = [shortcuts];
|
shortcuts = [shortcuts];
|
||||||
}
|
|
||||||
_.each(shortcuts, function (shortcut) {
|
|
||||||
$(document).bind('keydown', shortcut, callback);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
_.each(shortcuts, (shortcut) => {
|
||||||
|
$(document).bind('keydown', shortcut, callback);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -20,53 +20,51 @@ const LinkIconTooltip = require('./widget/LinkIconTooltip').default;
|
|||||||
|
|
||||||
const LinkIcon = new Class({
|
const LinkIcon = new Class({
|
||||||
|
|
||||||
Extends: Icon,
|
Extends: Icon,
|
||||||
initialize: function (topic, linkModel, readOnly) {
|
initialize(topic, linkModel, readOnly) {
|
||||||
$assert(topic, 'topic can not be null');
|
$assert(topic, 'topic can not be null');
|
||||||
$assert(linkModel, 'linkModel can not be null');
|
$assert(linkModel, 'linkModel can not be null');
|
||||||
|
|
||||||
this.parent(LinkIcon.IMAGE_URL);
|
this.parent(LinkIcon.IMAGE_URL);
|
||||||
this._linksModel = linkModel;
|
this._linksModel = linkModel;
|
||||||
this._topic = topic;
|
this._topic = topic;
|
||||||
this._readOnly = readOnly;
|
this._readOnly = readOnly;
|
||||||
|
|
||||||
this._registerEvents();
|
this._registerEvents();
|
||||||
},
|
},
|
||||||
|
|
||||||
_registerEvents: function () {
|
_registerEvents() {
|
||||||
this._image.setCursor('pointer');
|
this._image.setCursor('pointer');
|
||||||
this._tip = new LinkIconTooltip(this);
|
this._tip = new LinkIconTooltip(this);
|
||||||
|
|
||||||
var me = this;
|
const me = this;
|
||||||
if (!this._readOnly) {
|
if (!this._readOnly) {
|
||||||
// Add on click event to open the editor ...
|
// Add on click event to open the editor ...
|
||||||
this.addEvent('click', function (event) {
|
this.addEvent('click', (event) => {
|
||||||
me._tip.hide();
|
me._tip.hide();
|
||||||
me._topic.showLinkEditor();
|
me._topic.showLinkEditor();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
});
|
});
|
||||||
//FIXME: we shouldn't have timeout of that..
|
// FIXME: we shouldn't have timeout of that..
|
||||||
this.addEvent("mouseleave", function (event) {
|
this.addEvent('mouseleave', (event) => {
|
||||||
window.setTimeout(function () {
|
window.setTimeout(() => {
|
||||||
if (!$("#linkPopover:hover").length) {
|
if (!$('#linkPopover:hover').length) {
|
||||||
me._tip.hide();
|
me._tip.hide();
|
||||||
}
|
}
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
}, 100)
|
}, 100);
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
$(this.getImage()._peer._native).mouseenter(function () {
|
|
||||||
me._tip.show();
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
getModel: function () {
|
|
||||||
return this._linksModel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$(this.getImage()._peer._native).mouseenter(() => {
|
||||||
|
me._tip.show();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
getModel() {
|
||||||
|
return this._linksModel;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
LinkIcon.IMAGE_URL = "images/links.png";
|
LinkIcon.IMAGE_URL = 'images/links.png';
|
||||||
|
|
||||||
export default LinkIcon;
|
export default LinkIcon;
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,47 +18,46 @@
|
|||||||
const PersistenceManager = require('./PersistenceManager').default;
|
const PersistenceManager = require('./PersistenceManager').default;
|
||||||
|
|
||||||
const LocalStorageManager = new Class({
|
const LocalStorageManager = new Class({
|
||||||
Extends: PersistenceManager,
|
Extends: PersistenceManager,
|
||||||
initialize: function (documentUrl, forceLoad) {
|
initialize(documentUrl, forceLoad) {
|
||||||
this.parent();
|
this.parent();
|
||||||
this.documentUrl = documentUrl;
|
this.documentUrl = documentUrl;
|
||||||
this.forceLoad = forceLoad;
|
this.forceLoad = forceLoad;
|
||||||
|
},
|
||||||
|
|
||||||
|
saveMapXml(mapId, mapXml, pref, saveHistory, events) {
|
||||||
|
localStorage.setItem(`${mapId}-xml`, mapXml);
|
||||||
|
},
|
||||||
|
|
||||||
|
discardChanges(mapId) {
|
||||||
|
localStorage.removeItem(`${mapId}-xml`);
|
||||||
|
},
|
||||||
|
|
||||||
|
loadMapDom(mapId) {
|
||||||
|
let xml = localStorage.getItem(`${mapId}-xml`);
|
||||||
|
if (xml == null || this.forceLoad) {
|
||||||
|
$.ajax({
|
||||||
|
url: this.documentUrl.replace('{id}', mapId),
|
||||||
|
headers: { 'Content-Type': 'text/plain', Accept: 'application/xml' },
|
||||||
|
type: 'get',
|
||||||
|
dataType: 'text',
|
||||||
|
async: false,
|
||||||
|
success(response) {
|
||||||
|
xml = response;
|
||||||
},
|
},
|
||||||
|
});
|
||||||
saveMapXml: function (mapId, mapXml, pref, saveHistory, events) {
|
// If I could not load it from a file, hard code one.
|
||||||
localStorage.setItem(mapId + "-xml", mapXml);
|
if (xml == null) {
|
||||||
},
|
throw new Error('Map could not be loaded');
|
||||||
|
}
|
||||||
discardChanges: function (mapId) {
|
|
||||||
localStorage.removeItem(mapId + "-xml");
|
|
||||||
},
|
|
||||||
|
|
||||||
loadMapDom: function (mapId) {
|
|
||||||
var xml = localStorage.getItem(mapId + "-xml");
|
|
||||||
if (xml == null || this.forceLoad) {
|
|
||||||
$.ajax({
|
|
||||||
url: this.documentUrl.replace("{id}", mapId),
|
|
||||||
headers: {"Content-Type": "text/plain", "Accept": "application/xml"},
|
|
||||||
type: 'get',
|
|
||||||
dataType: "text",
|
|
||||||
async: false,
|
|
||||||
success: function (response) {
|
|
||||||
xml = response;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// If I could not load it from a file, hard code one.
|
|
||||||
if (xml == null) {
|
|
||||||
throw new Error("Map could not be loaded");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return jQuery.parseXML(xml);
|
|
||||||
},
|
|
||||||
|
|
||||||
unlockMap: function (mindmap) {
|
|
||||||
// Ignore, no implementation required ...
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
return jQuery.parseXML(xml);
|
||||||
|
},
|
||||||
|
|
||||||
|
unlockMap(mindmap) {
|
||||||
|
// Ignore, no implementation required ...
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export default LocalStorageManager;
|
export default LocalStorageManager;
|
||||||
|
@ -15,9 +15,11 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
const Core = require('@wismapping/core-js')
|
const Core = require('@wismapping/core-js');
|
||||||
|
|
||||||
const core = Core();
|
const core = Core();
|
||||||
const web2D = require('@wismapping/web2d');
|
const web2D = require('@wismapping/web2d');
|
||||||
|
|
||||||
const web2d = web2D();
|
const web2d = web2D();
|
||||||
|
|
||||||
const Topic = require('./Topic').default;
|
const Topic = require('./Topic').default;
|
||||||
@ -25,145 +27,144 @@ const { TopicShape } = require('./model/INodeModel');
|
|||||||
const Shape = require('./util/Shape').default;
|
const Shape = require('./util/Shape').default;
|
||||||
|
|
||||||
const MainTopic = new Class(/** @lends MainTopic */ {
|
const MainTopic = new Class(/** @lends MainTopic */ {
|
||||||
Extends: Topic,
|
Extends: Topic,
|
||||||
/**
|
/**
|
||||||
* @extends mindplot.Topic
|
* @extends mindplot.Topic
|
||||||
* @constructs
|
* @constructs
|
||||||
* @param model
|
* @param model
|
||||||
* @param options
|
* @param options
|
||||||
*/
|
*/
|
||||||
initialize: function (model, options) {
|
initialize(model, options) {
|
||||||
this.parent(model, options);
|
this.parent(model, options);
|
||||||
},
|
},
|
||||||
|
|
||||||
INNER_RECT_ATTRIBUTES: { stroke: '0.5 solid #009900' },
|
INNER_RECT_ATTRIBUTES: { stroke: '0.5 solid #009900' },
|
||||||
|
|
||||||
_buildDragShape: function () {
|
_buildDragShape() {
|
||||||
var innerShape = this._buildShape(this.INNER_RECT_ATTRIBUTES, this.getShapeType());
|
const innerShape = this._buildShape(this.INNER_RECT_ATTRIBUTES, this.getShapeType());
|
||||||
var size = this.getSize();
|
const size = this.getSize();
|
||||||
innerShape.setSize(size.width, size.height);
|
innerShape.setSize(size.width, size.height);
|
||||||
innerShape.setPosition(0, 0);
|
innerShape.setPosition(0, 0);
|
||||||
innerShape.setOpacity(0.5);
|
innerShape.setOpacity(0.5);
|
||||||
innerShape.setCursor('default');
|
innerShape.setCursor('default');
|
||||||
innerShape.setVisibility(true);
|
innerShape.setVisibility(true);
|
||||||
|
|
||||||
var brColor = this.getBorderColor();
|
const brColor = this.getBorderColor();
|
||||||
innerShape.setAttribute('strokeColor', brColor);
|
innerShape.setAttribute('strokeColor', brColor);
|
||||||
|
|
||||||
var bgColor = this.getBackgroundColor();
|
const bgColor = this.getBackgroundColor();
|
||||||
innerShape.setAttribute('fillColor', bgColor);
|
innerShape.setAttribute('fillColor', bgColor);
|
||||||
|
|
||||||
// Create group ...
|
// Create group ...
|
||||||
var groupAttributes = {
|
const groupAttributes = {
|
||||||
width: 100,
|
width: 100,
|
||||||
height: 100,
|
height: 100,
|
||||||
coordSizeWidth: 100,
|
coordSizeWidth: 100,
|
||||||
coordSizeHeight: 100,
|
coordSizeHeight: 100,
|
||||||
};
|
};
|
||||||
var group = new web2d.Group(groupAttributes);
|
const group = new web2d.Group(groupAttributes);
|
||||||
group.append(innerShape);
|
group.append(innerShape);
|
||||||
|
|
||||||
// Add Text ...
|
// Add Text ...
|
||||||
if (this.getShapeType() != TopicShape.IMAGE) {
|
if (this.getShapeType() != TopicShape.IMAGE) {
|
||||||
var textShape = this._buildTextShape(true);
|
const textShape = this._buildTextShape(true);
|
||||||
var text = this.getText();
|
const text = this.getText();
|
||||||
textShape.setText(text);
|
textShape.setText(text);
|
||||||
textShape.setOpacity(0.5);
|
textShape.setOpacity(0.5);
|
||||||
group.append(textShape);
|
group.append(textShape);
|
||||||
}
|
|
||||||
return group;
|
|
||||||
},
|
|
||||||
|
|
||||||
/** */
|
|
||||||
updateTopicShape: function (targetTopic, workspace) {
|
|
||||||
// Change figure based on the connected topic ...
|
|
||||||
var model = this.getModel();
|
|
||||||
var shapeType = model.getShapeType();
|
|
||||||
if (!targetTopic.isCentralTopic()) {
|
|
||||||
if (!$defined(shapeType)) {
|
|
||||||
// Get the real shape type ...
|
|
||||||
shapeType = this.getShapeType();
|
|
||||||
this._setShapeType(shapeType, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/** */
|
|
||||||
disconnect: function (workspace) {
|
|
||||||
this.parent(workspace);
|
|
||||||
var size = this.getSize();
|
|
||||||
|
|
||||||
var model = this.getModel();
|
|
||||||
var shapeType = model.getShapeType();
|
|
||||||
if (!$defined(shapeType)) {
|
|
||||||
// Change figure ...
|
|
||||||
shapeType = this.getShapeType();
|
|
||||||
this._setShapeType(TopicShape.ROUNDED_RECT, false);
|
|
||||||
}
|
|
||||||
var innerShape = this.getInnerShape();
|
|
||||||
innerShape.setVisibility(true);
|
|
||||||
},
|
|
||||||
|
|
||||||
_updatePositionOnChangeSize: function (oldSize, newSize) {
|
|
||||||
var xOffset = Math.round((newSize.width - oldSize.width) / 2);
|
|
||||||
var pos = this.getPosition();
|
|
||||||
if ($defined(pos)) {
|
|
||||||
if (pos.x > 0) {
|
|
||||||
pos.x = pos.x + xOffset;
|
|
||||||
} else {
|
|
||||||
pos.x = pos.x - xOffset;
|
|
||||||
}
|
|
||||||
this.setPosition(pos);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/** */
|
|
||||||
workoutIncomingConnectionPoint: function (sourcePosition) {
|
|
||||||
return Shape.workoutIncomingConnectionPoint(this, sourcePosition);
|
|
||||||
},
|
|
||||||
|
|
||||||
/** */
|
|
||||||
workoutOutgoingConnectionPoint: function (targetPosition) {
|
|
||||||
$assert(targetPosition, 'targetPoint can not be null');
|
|
||||||
var pos = this.getPosition();
|
|
||||||
var isAtRight = Shape.isAtRight(targetPosition, pos);
|
|
||||||
var size = this.getSize();
|
|
||||||
|
|
||||||
var result;
|
|
||||||
if (this.getShapeType() == TopicShape.LINE) {
|
|
||||||
result = new core.Point();
|
|
||||||
var groupPosition = this._elem2d.getPosition();
|
|
||||||
var innerShareSize = this.getInnerShape().getSize();
|
|
||||||
|
|
||||||
if (innerShareSize) {
|
|
||||||
var magicCorrectionNumber = 0.3;
|
|
||||||
if (!isAtRight) {
|
|
||||||
result.x = groupPosition.x + innerShareSize.width - magicCorrectionNumber;
|
|
||||||
} else {
|
|
||||||
result.x = groupPosition.x + magicCorrectionNumber;
|
|
||||||
}
|
|
||||||
result.y = groupPosition.y + innerShareSize.height;
|
|
||||||
} else {
|
|
||||||
// Hack: When the size has not being defined. This is because the node has not being added.
|
|
||||||
// Try to do our best ...
|
|
||||||
if (!isAtRight) {
|
|
||||||
result.x = pos.x + size.width / 2;
|
|
||||||
} else {
|
|
||||||
result.x = pos.x - size.width / 2;
|
|
||||||
}
|
|
||||||
result.y = pos.y + size.height / 2;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result = Shape.calculateRectConnectionPoint(
|
|
||||||
pos,
|
|
||||||
size,
|
|
||||||
isAtRight,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
);
|
return group;
|
||||||
|
},
|
||||||
|
|
||||||
|
/** */
|
||||||
|
updateTopicShape(targetTopic, workspace) {
|
||||||
|
// Change figure based on the connected topic ...
|
||||||
|
const model = this.getModel();
|
||||||
|
let shapeType = model.getShapeType();
|
||||||
|
if (!targetTopic.isCentralTopic()) {
|
||||||
|
if (!$defined(shapeType)) {
|
||||||
|
// Get the real shape type ...
|
||||||
|
shapeType = this.getShapeType();
|
||||||
|
this._setShapeType(shapeType, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/** */
|
||||||
|
disconnect(workspace) {
|
||||||
|
this.parent(workspace);
|
||||||
|
const size = this.getSize();
|
||||||
|
|
||||||
|
const model = this.getModel();
|
||||||
|
let shapeType = model.getShapeType();
|
||||||
|
if (!$defined(shapeType)) {
|
||||||
|
// Change figure ...
|
||||||
|
shapeType = this.getShapeType();
|
||||||
|
this._setShapeType(TopicShape.ROUNDED_RECT, false);
|
||||||
|
}
|
||||||
|
const innerShape = this.getInnerShape();
|
||||||
|
innerShape.setVisibility(true);
|
||||||
|
},
|
||||||
|
|
||||||
|
_updatePositionOnChangeSize(oldSize, newSize) {
|
||||||
|
const xOffset = Math.round((newSize.width - oldSize.width) / 2);
|
||||||
|
const pos = this.getPosition();
|
||||||
|
if ($defined(pos)) {
|
||||||
|
if (pos.x > 0) {
|
||||||
|
pos.x += xOffset;
|
||||||
|
} else {
|
||||||
|
pos.x -= xOffset;
|
||||||
|
}
|
||||||
|
this.setPosition(pos);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/** */
|
||||||
|
workoutIncomingConnectionPoint(sourcePosition) {
|
||||||
|
return Shape.workoutIncomingConnectionPoint(this, sourcePosition);
|
||||||
|
},
|
||||||
|
|
||||||
|
/** */
|
||||||
|
workoutOutgoingConnectionPoint(targetPosition) {
|
||||||
|
$assert(targetPosition, 'targetPoint can not be null');
|
||||||
|
const pos = this.getPosition();
|
||||||
|
const isAtRight = Shape.isAtRight(targetPosition, pos);
|
||||||
|
const size = this.getSize();
|
||||||
|
|
||||||
|
let result;
|
||||||
|
if (this.getShapeType() == TopicShape.LINE) {
|
||||||
|
result = new core.Point();
|
||||||
|
const groupPosition = this._elem2d.getPosition();
|
||||||
|
const innerShareSize = this.getInnerShape().getSize();
|
||||||
|
|
||||||
|
if (innerShareSize) {
|
||||||
|
const magicCorrectionNumber = 0.3;
|
||||||
|
if (!isAtRight) {
|
||||||
|
result.x = groupPosition.x + innerShareSize.width - magicCorrectionNumber;
|
||||||
|
} else {
|
||||||
|
result.x = groupPosition.x + magicCorrectionNumber;
|
||||||
|
}
|
||||||
|
result.y = groupPosition.y + innerShareSize.height;
|
||||||
|
} else {
|
||||||
|
// Hack: When the size has not being defined. This is because the node has not being added.
|
||||||
|
// Try to do our best ...
|
||||||
|
if (!isAtRight) {
|
||||||
|
result.x = pos.x + size.width / 2;
|
||||||
|
} else {
|
||||||
|
result.x = pos.x - size.width / 2;
|
||||||
|
}
|
||||||
|
result.y = pos.y + size.height / 2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result = Shape.calculateRectConnectionPoint(
|
||||||
|
pos,
|
||||||
|
size,
|
||||||
|
isAtRight,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export default MainTopic;
|
export default MainTopic;
|
||||||
|
@ -17,27 +17,27 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const Messages = new Class({
|
const Messages = new Class({
|
||||||
Static: {
|
Static: {
|
||||||
init: function (locale) {
|
init(locale) {
|
||||||
locale = $defined(locale) ? locale : 'en';
|
locale = $defined(locale) ? locale : 'en';
|
||||||
var bundle = Messages.BUNDLES[locale];
|
let bundle = Messages.BUNDLES[locale];
|
||||||
if (bundle == null && locale.indexOf('_') != -1) {
|
if (bundle == null && locale.indexOf('_') != -1) {
|
||||||
// Try to locate without the specialization ...
|
// Try to locate without the specialization ...
|
||||||
locale = locale.substring(0, locale.indexOf('_'));
|
locale = locale.substring(0, locale.indexOf('_'));
|
||||||
bundle = Messages.BUNDLES[locale];
|
bundle = Messages.BUNDLES[locale];
|
||||||
}
|
}
|
||||||
Messages.__bundle = bundle;
|
Messages.__bundle = bundle;
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
global.$msg = function (key) {
|
global.$msg = function (key) {
|
||||||
if (!Messages.__bundle) {
|
if (!Messages.__bundle) {
|
||||||
Messages.init('en');
|
Messages.init('en');
|
||||||
}
|
}
|
||||||
|
|
||||||
var msg = Messages.__bundle[key];
|
const msg = Messages.__bundle[key];
|
||||||
return msg ? msg : key;
|
return msg || key;
|
||||||
};
|
};
|
||||||
|
|
||||||
Messages.BUNDLES = {};
|
Messages.BUNDLES = {};
|
||||||
|
@ -19,298 +19,285 @@ const Events = require('./Events').default;
|
|||||||
const ActionDispatcher = require('./ActionDispatcher').default;
|
const ActionDispatcher = require('./ActionDispatcher').default;
|
||||||
|
|
||||||
const MultilineTextEditor = new Class({
|
const MultilineTextEditor = new Class({
|
||||||
Extends: Events,
|
Extends: Events,
|
||||||
initialize: function () {
|
initialize() {
|
||||||
this._topic = null;
|
this._topic = null;
|
||||||
this._timeoutId = -1;
|
this._timeoutId = -1;
|
||||||
},
|
},
|
||||||
|
|
||||||
_buildEditor: function () {
|
_buildEditor() {
|
||||||
|
const result = $('<div></div>')
|
||||||
|
.attr('id', 'textContainer')
|
||||||
|
.css({
|
||||||
|
display: 'none',
|
||||||
|
zIndex: '8',
|
||||||
|
overflow: 'hidden',
|
||||||
|
border: '0 none',
|
||||||
|
});
|
||||||
|
|
||||||
var result = $('<div></div>')
|
const textareaElem = $('<textarea tabindex="-1" value="" wrap="off" ></textarea>')
|
||||||
.attr('id', 'textContainer')
|
.css({
|
||||||
.css({
|
border: '1px gray dashed',
|
||||||
display: "none",
|
background: 'rgba(98, 135, 167, .3)',
|
||||||
zIndex: "8",
|
outline: '0 none',
|
||||||
overflow: "hidden",
|
resize: 'none',
|
||||||
border: "0 none"
|
overflow: 'hidden',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
result.append(textareaElem);
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
var textareaElem = $('<textarea tabindex="-1" value="" wrap="off" ></textarea>')
|
_registerEvents(containerElem) {
|
||||||
.css({
|
const textareaElem = this._getTextareaElem();
|
||||||
border: "1px gray dashed",
|
const me = this;
|
||||||
background: "rgba(98, 135, 167, .3)",
|
textareaElem.on('keydown', function (event) {
|
||||||
outline: '0 none',
|
switch (jQuery.hotkeys.specialKeys[event.keyCode]) {
|
||||||
resize: 'none',
|
case 'esc':
|
||||||
overflow: "hidden"
|
me.close(false);
|
||||||
});
|
break;
|
||||||
|
case 'enter':
|
||||||
result.append(textareaElem);
|
if (event.metaKey || event.ctrlKey) {
|
||||||
return result;
|
// Add return ...
|
||||||
},
|
const text = textareaElem.val();
|
||||||
|
let cursorPosition = text.length;
|
||||||
_registerEvents: function (containerElem) {
|
if (textareaElem.selectionStart) {
|
||||||
var textareaElem = this._getTextareaElem();
|
cursorPosition = textareaElem.selectionStart;
|
||||||
var me = this;
|
|
||||||
textareaElem.on('keydown', function (event) {
|
|
||||||
switch (jQuery.hotkeys.specialKeys[event.keyCode]) {
|
|
||||||
case 'esc':
|
|
||||||
me.close(false);
|
|
||||||
break;
|
|
||||||
case 'enter':
|
|
||||||
if (event.metaKey || event.ctrlKey) {
|
|
||||||
|
|
||||||
// Add return ...
|
|
||||||
var text = textareaElem.val();
|
|
||||||
var cursorPosition = text.length;
|
|
||||||
if (textareaElem.selectionStart) {
|
|
||||||
cursorPosition = textareaElem.selectionStart;
|
|
||||||
}
|
|
||||||
|
|
||||||
var head = text.substring(0, cursorPosition);
|
|
||||||
var tail = "";
|
|
||||||
if (cursorPosition < text.length) {
|
|
||||||
tail = text.substring(cursorPosition, text.length);
|
|
||||||
}
|
|
||||||
textareaElem.val(head + "\n" + tail);
|
|
||||||
|
|
||||||
// Position cursor ...
|
|
||||||
if (textareaElem[0].setSelectionRange) {
|
|
||||||
textareaElem.focus();
|
|
||||||
textareaElem[0].setSelectionRange(cursorPosition + 1, cursorPosition + 1);
|
|
||||||
} else if (textareaElem.createTextRange) {
|
|
||||||
var range = textareaElem.createTextRange();
|
|
||||||
range.moveStart('character', cursorPosition + 1);
|
|
||||||
range.select();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
me.close(true);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'tab':
|
|
||||||
event.preventDefault();
|
|
||||||
var start = $(this).get(0).selectionStart;
|
|
||||||
var end = $(this).get(0).selectionEnd;
|
|
||||||
|
|
||||||
// set textarea value to: text before caret + tab + text after caret
|
|
||||||
$(this).val($(this).val().substring(0, start) + "\t" + $(this).val().substring(end));
|
|
||||||
|
|
||||||
// put caret at right position again
|
|
||||||
$(this).get(0).selectionStart = $(this).get(0).selectionEnd = start + 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
event.stopPropagation();
|
|
||||||
});
|
|
||||||
|
|
||||||
textareaElem.on('keypress', function (event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
});
|
|
||||||
|
|
||||||
textareaElem.on('keyup', function (event) {
|
|
||||||
var text = me._getTextareaElem().val();
|
|
||||||
me.fireEvent('input', [event, text]);
|
|
||||||
me._adjustEditorSize();
|
|
||||||
});
|
|
||||||
|
|
||||||
// If the user clicks on the input, all event must be ignored ...
|
|
||||||
containerElem.on('click', function (event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
});
|
|
||||||
containerElem.on('dblclick', function (event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
});
|
|
||||||
containerElem.on('mousedown', function (event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
_adjustEditorSize: function () {
|
|
||||||
|
|
||||||
if (this.isVisible()) {
|
|
||||||
var textElem = this._getTextareaElem();
|
|
||||||
|
|
||||||
var lines = textElem.val().split('\n');
|
|
||||||
var maxLineLength = 1;
|
|
||||||
_.each(lines, function (line) {
|
|
||||||
if (maxLineLength < line.length)
|
|
||||||
maxLineLength = line.length;
|
|
||||||
});
|
|
||||||
|
|
||||||
textElem.attr('cols', maxLineLength);
|
|
||||||
textElem.attr('rows', lines.length);
|
|
||||||
|
|
||||||
this._containerElem.css({
|
|
||||||
width: (maxLineLength + 3) + 'em',
|
|
||||||
height: textElem.height()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
isVisible: function () {
|
|
||||||
return $defined(this._containerElem) && this._containerElem.css('display') == 'block';
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateModel: function () {
|
|
||||||
|
|
||||||
if (this._topic.getText() != this._getText()) {
|
|
||||||
var text = this._getText();
|
|
||||||
var topicId = this._topic.getId();
|
|
||||||
|
|
||||||
var actionDispatcher = ActionDispatcher.getInstance();
|
|
||||||
actionDispatcher.changeTextToTopic([topicId], text);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
show: function (topic, text) {
|
|
||||||
// Close a previous node editor if it's opened ...
|
|
||||||
if (this._topic) {
|
|
||||||
this.close(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._topic = topic;
|
|
||||||
if (!this.isVisible()) {
|
|
||||||
//Create editor ui
|
|
||||||
var containerElem = this._buildEditor();
|
|
||||||
$('body').append(containerElem);
|
|
||||||
|
|
||||||
this._containerElem = containerElem;
|
|
||||||
this._registerEvents(containerElem);
|
|
||||||
this._showEditor(text);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_showEditor: function (defaultText) {
|
|
||||||
|
|
||||||
var topic = this._topic;
|
|
||||||
|
|
||||||
// Hide topic text ...
|
|
||||||
topic.getTextShape().setVisibility(false);
|
|
||||||
|
|
||||||
// Set Editor Style
|
|
||||||
var nodeText = topic.getTextShape();
|
|
||||||
var font = nodeText.getFont();
|
|
||||||
font.size = nodeText.getHtmlFontSize();
|
|
||||||
font.color = nodeText.getColor();
|
|
||||||
this._setStyle(font);
|
|
||||||
var me = this;
|
|
||||||
// Set editor's initial size
|
|
||||||
var displayFunc = function () {
|
|
||||||
// Position the editor and set the size...
|
|
||||||
var textShape = topic.getTextShape();
|
|
||||||
|
|
||||||
me._containerElem.css('display', 'block');
|
|
||||||
|
|
||||||
//FIXME: Im not sure if this is best way...
|
|
||||||
var shapePosition = textShape.getNativePosition();
|
|
||||||
me._containerElem.offset(shapePosition);
|
|
||||||
|
|
||||||
// Set editor's initial text ...
|
|
||||||
var text = $defined(defaultText) ? defaultText : topic.getText();
|
|
||||||
me._setText(text);
|
|
||||||
|
|
||||||
// Set the element focus and select the current text ...
|
|
||||||
var inputElem = me._getTextareaElem();
|
|
||||||
me._positionCursor(inputElem, !$defined(defaultText));
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
this._timeoutId = displayFunc.delay(10);
|
|
||||||
},
|
|
||||||
|
|
||||||
_setStyle: function (fontStyle) {
|
|
||||||
var inputField = this._getTextareaElem();
|
|
||||||
if (!$defined(fontStyle.font)) {
|
|
||||||
fontStyle.font = "Arial";
|
|
||||||
}
|
|
||||||
if (!$defined(fontStyle.style)) {
|
|
||||||
fontStyle.style = "normal";
|
|
||||||
}
|
|
||||||
if (!$defined(fontStyle.weight)) {
|
|
||||||
fontStyle.weight = "normal";
|
|
||||||
}
|
|
||||||
if (!$defined(fontStyle.size)) {
|
|
||||||
fontStyle.size = 12;
|
|
||||||
}
|
|
||||||
var style = {
|
|
||||||
fontSize: fontStyle.size + "px",
|
|
||||||
fontFamily: fontStyle.font,
|
|
||||||
fontStyle: fontStyle.style,
|
|
||||||
fontWeight: fontStyle.weight,
|
|
||||||
color: fontStyle.color
|
|
||||||
};
|
|
||||||
inputField.css(style);
|
|
||||||
this._containerElem.css(style);
|
|
||||||
},
|
|
||||||
|
|
||||||
_setText: function (text) {
|
|
||||||
var textareaElem = this._getTextareaElem();
|
|
||||||
textareaElem.val(text);
|
|
||||||
this._adjustEditorSize();
|
|
||||||
},
|
|
||||||
|
|
||||||
_getText: function () {
|
|
||||||
return this._getTextareaElem().val();
|
|
||||||
},
|
|
||||||
|
|
||||||
_getTextareaElem: function () {
|
|
||||||
return this._containerElem.find('textarea');
|
|
||||||
},
|
|
||||||
|
|
||||||
_positionCursor: function (textareaElem, selectText) {
|
|
||||||
textareaElem.focus();
|
|
||||||
var lengh = textareaElem.val().length;
|
|
||||||
if (selectText) {
|
|
||||||
// Mark text as selected ...
|
|
||||||
if (textareaElem.createTextRange) {
|
|
||||||
var rang = textareaElem.createTextRange();
|
|
||||||
rang.select();
|
|
||||||
rang.move("character", lengh);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
textareaElem[0].setSelectionRange(0, lengh);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
const head = text.substring(0, cursorPosition);
|
||||||
// Move the cursor to the last character ..
|
let tail = '';
|
||||||
if (textareaElem.createTextRange) {
|
if (cursorPosition < text.length) {
|
||||||
var range = textareaElem.createTextRange();
|
tail = text.substring(cursorPosition, text.length);
|
||||||
range.move("character", lengh);
|
|
||||||
} else {
|
|
||||||
if (Browser.ie11) {
|
|
||||||
textareaElem[0].selectionStart = lengh;
|
|
||||||
textareaElem[0].selectionEnd = lengh;
|
|
||||||
} else {
|
|
||||||
textareaElem.selectionStart = lengh;
|
|
||||||
textareaElem.selectionEnd = lengh;
|
|
||||||
}
|
|
||||||
textareaElem.focus();
|
|
||||||
}
|
}
|
||||||
}
|
textareaElem.val(`${head}\n${tail}`);
|
||||||
|
|
||||||
},
|
// Position cursor ...
|
||||||
|
if (textareaElem[0].setSelectionRange) {
|
||||||
close: function (update) {
|
textareaElem.focus();
|
||||||
if (this.isVisible() && this._topic) {
|
textareaElem[0].setSelectionRange(cursorPosition + 1, cursorPosition + 1);
|
||||||
// Update changes ...
|
} else if (textareaElem.createTextRange) {
|
||||||
clearTimeout(this._timeoutId);
|
const range = textareaElem.createTextRange();
|
||||||
|
range.moveStart('character', cursorPosition + 1);
|
||||||
if (!$defined(update) || update) {
|
range.select();
|
||||||
this._updateModel();
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
me.close(true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'tab':
|
||||||
|
event.preventDefault();
|
||||||
|
var start = $(this).get(0).selectionStart;
|
||||||
|
var end = $(this).get(0).selectionEnd;
|
||||||
|
|
||||||
// Let make the visible text in the node visible again ...
|
// set textarea value to: text before caret + tab + text after caret
|
||||||
this._topic.getTextShape().setVisibility(true);
|
$(this).val(`${$(this).val().substring(0, start)}\t${$(this).val().substring(end)}`);
|
||||||
|
|
||||||
// Remove it form the screen ...
|
// put caret at right position again
|
||||||
this._containerElem.remove();
|
$(this).get(0).selectionStart = $(this).get(0).selectionEnd = start + 1;
|
||||||
this._containerElem = null;
|
break;
|
||||||
this._timeoutId = -1;
|
}
|
||||||
}
|
event.stopPropagation();
|
||||||
this._topic = null;
|
});
|
||||||
|
|
||||||
|
textareaElem.on('keypress', (event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
});
|
||||||
|
|
||||||
|
textareaElem.on('keyup', (event) => {
|
||||||
|
const text = me._getTextareaElem().val();
|
||||||
|
me.fireEvent('input', [event, text]);
|
||||||
|
me._adjustEditorSize();
|
||||||
|
});
|
||||||
|
|
||||||
|
// If the user clicks on the input, all event must be ignored ...
|
||||||
|
containerElem.on('click', (event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
});
|
||||||
|
containerElem.on('dblclick', (event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
});
|
||||||
|
containerElem.on('mousedown', (event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_adjustEditorSize() {
|
||||||
|
if (this.isVisible()) {
|
||||||
|
const textElem = this._getTextareaElem();
|
||||||
|
|
||||||
|
const lines = textElem.val().split('\n');
|
||||||
|
let maxLineLength = 1;
|
||||||
|
_.each(lines, (line) => {
|
||||||
|
if (maxLineLength < line.length) maxLineLength = line.length;
|
||||||
|
});
|
||||||
|
|
||||||
|
textElem.attr('cols', maxLineLength);
|
||||||
|
textElem.attr('rows', lines.length);
|
||||||
|
|
||||||
|
this._containerElem.css({
|
||||||
|
width: `${maxLineLength + 3}em`,
|
||||||
|
height: textElem.height(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
isVisible() {
|
||||||
|
return $defined(this._containerElem) && this._containerElem.css('display') == 'block';
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateModel() {
|
||||||
|
if (this._topic.getText() != this._getText()) {
|
||||||
|
const text = this._getText();
|
||||||
|
const topicId = this._topic.getId();
|
||||||
|
|
||||||
|
const actionDispatcher = ActionDispatcher.getInstance();
|
||||||
|
actionDispatcher.changeTextToTopic([topicId], text);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
show(topic, text) {
|
||||||
|
// Close a previous node editor if it's opened ...
|
||||||
|
if (this._topic) {
|
||||||
|
this.close(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._topic = topic;
|
||||||
|
if (!this.isVisible()) {
|
||||||
|
// Create editor ui
|
||||||
|
const containerElem = this._buildEditor();
|
||||||
|
$('body').append(containerElem);
|
||||||
|
|
||||||
|
this._containerElem = containerElem;
|
||||||
|
this._registerEvents(containerElem);
|
||||||
|
this._showEditor(text);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_showEditor(defaultText) {
|
||||||
|
const topic = this._topic;
|
||||||
|
|
||||||
|
// Hide topic text ...
|
||||||
|
topic.getTextShape().setVisibility(false);
|
||||||
|
|
||||||
|
// Set Editor Style
|
||||||
|
const nodeText = topic.getTextShape();
|
||||||
|
const font = nodeText.getFont();
|
||||||
|
font.size = nodeText.getHtmlFontSize();
|
||||||
|
font.color = nodeText.getColor();
|
||||||
|
this._setStyle(font);
|
||||||
|
const me = this;
|
||||||
|
// Set editor's initial size
|
||||||
|
const displayFunc = function () {
|
||||||
|
// Position the editor and set the size...
|
||||||
|
const textShape = topic.getTextShape();
|
||||||
|
|
||||||
|
me._containerElem.css('display', 'block');
|
||||||
|
|
||||||
|
// FIXME: Im not sure if this is best way...
|
||||||
|
const shapePosition = textShape.getNativePosition();
|
||||||
|
me._containerElem.offset(shapePosition);
|
||||||
|
|
||||||
|
// Set editor's initial text ...
|
||||||
|
const text = $defined(defaultText) ? defaultText : topic.getText();
|
||||||
|
me._setText(text);
|
||||||
|
|
||||||
|
// Set the element focus and select the current text ...
|
||||||
|
const inputElem = me._getTextareaElem();
|
||||||
|
me._positionCursor(inputElem, !$defined(defaultText));
|
||||||
|
};
|
||||||
|
|
||||||
|
this._timeoutId = displayFunc.delay(10);
|
||||||
|
},
|
||||||
|
|
||||||
|
_setStyle(fontStyle) {
|
||||||
|
const inputField = this._getTextareaElem();
|
||||||
|
if (!$defined(fontStyle.font)) {
|
||||||
|
fontStyle.font = 'Arial';
|
||||||
|
}
|
||||||
|
if (!$defined(fontStyle.style)) {
|
||||||
|
fontStyle.style = 'normal';
|
||||||
|
}
|
||||||
|
if (!$defined(fontStyle.weight)) {
|
||||||
|
fontStyle.weight = 'normal';
|
||||||
|
}
|
||||||
|
if (!$defined(fontStyle.size)) {
|
||||||
|
fontStyle.size = 12;
|
||||||
|
}
|
||||||
|
const style = {
|
||||||
|
fontSize: `${fontStyle.size}px`,
|
||||||
|
fontFamily: fontStyle.font,
|
||||||
|
fontStyle: fontStyle.style,
|
||||||
|
fontWeight: fontStyle.weight,
|
||||||
|
color: fontStyle.color,
|
||||||
|
};
|
||||||
|
inputField.css(style);
|
||||||
|
this._containerElem.css(style);
|
||||||
|
},
|
||||||
|
|
||||||
|
_setText(text) {
|
||||||
|
const textareaElem = this._getTextareaElem();
|
||||||
|
textareaElem.val(text);
|
||||||
|
this._adjustEditorSize();
|
||||||
|
},
|
||||||
|
|
||||||
|
_getText() {
|
||||||
|
return this._getTextareaElem().val();
|
||||||
|
},
|
||||||
|
|
||||||
|
_getTextareaElem() {
|
||||||
|
return this._containerElem.find('textarea');
|
||||||
|
},
|
||||||
|
|
||||||
|
_positionCursor(textareaElem, selectText) {
|
||||||
|
textareaElem.focus();
|
||||||
|
const lengh = textareaElem.val().length;
|
||||||
|
if (selectText) {
|
||||||
|
// Mark text as selected ...
|
||||||
|
if (textareaElem.createTextRange) {
|
||||||
|
const rang = textareaElem.createTextRange();
|
||||||
|
rang.select();
|
||||||
|
rang.move('character', lengh);
|
||||||
|
} else {
|
||||||
|
textareaElem[0].setSelectionRange(0, lengh);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Move the cursor to the last character ..
|
||||||
|
if (textareaElem.createTextRange) {
|
||||||
|
const range = textareaElem.createTextRange();
|
||||||
|
range.move('character', lengh);
|
||||||
|
} else {
|
||||||
|
if (Browser.ie11) {
|
||||||
|
textareaElem[0].selectionStart = lengh;
|
||||||
|
textareaElem[0].selectionEnd = lengh;
|
||||||
|
} else {
|
||||||
|
textareaElem.selectionStart = lengh;
|
||||||
|
textareaElem.selectionEnd = lengh;
|
||||||
|
}
|
||||||
|
textareaElem.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
close(update) {
|
||||||
|
if (this.isVisible() && this._topic) {
|
||||||
|
// Update changes ...
|
||||||
|
clearTimeout(this._timeoutId);
|
||||||
|
|
||||||
|
if (!$defined(update) || update) {
|
||||||
|
this._updateModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let make the visible text in the node visible again ...
|
||||||
|
this._topic.getTextShape().setVisibility(true);
|
||||||
|
|
||||||
|
// Remove it form the screen ...
|
||||||
|
this._containerElem.remove();
|
||||||
|
this._containerElem = null;
|
||||||
|
this._timeoutId = -1;
|
||||||
|
}
|
||||||
|
this._topic = null;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default MultilineTextEditor;
|
export default MultilineTextEditor;
|
||||||
|
@ -20,171 +20,171 @@ const DragTopic = require('./DragTopic').default;
|
|||||||
const INodeModel = require('./model/INodeModel').default;
|
const INodeModel = require('./model/INodeModel').default;
|
||||||
|
|
||||||
const NodeGraph = new Class(
|
const NodeGraph = new Class(
|
||||||
/** @lends NodeGraph */ {
|
/** @lends NodeGraph */ {
|
||||||
/**
|
/**
|
||||||
* @constructs
|
* @constructs
|
||||||
* @param {mindplot.model.NodeModel} nodeModel
|
* @param {mindplot.model.NodeModel} nodeModel
|
||||||
* @param {Object<Number, String, Boolean>} options
|
* @param {Object<Number, String, Boolean>} options
|
||||||
* @throws will throw an error if nodeModel is null or undefined
|
* @throws will throw an error if nodeModel is null or undefined
|
||||||
*/
|
*/
|
||||||
initialize: function (nodeModel, options) {
|
initialize(nodeModel, options) {
|
||||||
$assert(nodeModel, 'model can not be null');
|
$assert(nodeModel, 'model can not be null');
|
||||||
|
|
||||||
this._options = options;
|
this._options = options;
|
||||||
this._mouseEvents = true;
|
this._mouseEvents = true;
|
||||||
this.setModel(nodeModel);
|
this.setModel(nodeModel);
|
||||||
this._onFocus = false;
|
this._onFocus = false;
|
||||||
this._size = { width: 50, height: 20 };
|
this._size = { width: 50, height: 20 };
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @return true if option is set to read-only */
|
/** @return true if option is set to read-only */
|
||||||
isReadOnly: function () {
|
isReadOnly() {
|
||||||
return this._options.readOnly;
|
return this._options.readOnly;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @return model type */
|
/** @return model type */
|
||||||
getType: function () {
|
getType() {
|
||||||
var model = this.getModel();
|
const model = this.getModel();
|
||||||
return model.getType();
|
return model.getType();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {String} id
|
* @param {String} id
|
||||||
* @throws will throw an error if the topic id is not a number
|
* @throws will throw an error if the topic id is not a number
|
||||||
*/
|
*/
|
||||||
setId: function (id) {
|
setId(id) {
|
||||||
$assert(typeof topic.getId() == 'number', 'id is not a number:' + id);
|
$assert(typeof topic.getId() === 'number', `id is not a number:${id}`);
|
||||||
this.getModel().setId(id);
|
this.getModel().setId(id);
|
||||||
},
|
},
|
||||||
|
|
||||||
_set2DElement: function (elem2d) {
|
_set2DElement(elem2d) {
|
||||||
this._elem2d = elem2d;
|
this._elem2d = elem2d;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return 2D element
|
* @return 2D element
|
||||||
* @throws will throw an error if the element is null or undefined within node graph
|
* @throws will throw an error if the element is null or undefined within node graph
|
||||||
*/
|
*/
|
||||||
get2DElement: function () {
|
get2DElement() {
|
||||||
$assert(this._elem2d, 'NodeGraph has not been initialized properly');
|
$assert(this._elem2d, 'NodeGraph has not been initialized properly');
|
||||||
return this._elem2d;
|
return this._elem2d;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
setPosition: function (point, fireEvent) {
|
setPosition(point, fireEvent) {
|
||||||
throw 'Unsupported operation';
|
throw 'Unsupported operation';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
addEvent: function (type, listener) {
|
addEvent(type, listener) {
|
||||||
var elem = this.get2DElement();
|
const elem = this.get2DElement();
|
||||||
elem.addEvent(type, listener);
|
elem.addEvent(type, listener);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
removeEvent: function (type, listener) {
|
removeEvent(type, listener) {
|
||||||
var elem = this.get2DElement();
|
const elem = this.get2DElement();
|
||||||
elem.removeEvent(type, listener);
|
elem.removeEvent(type, listener);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
fireEvent: function (type, event) {
|
fireEvent(type, event) {
|
||||||
var elem = this.get2DElement();
|
const elem = this.get2DElement();
|
||||||
elem.trigger(type, event);
|
elem.trigger(type, event);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setMouseEventsEnabled: function (isEnabled) {
|
setMouseEventsEnabled(isEnabled) {
|
||||||
this._mouseEvents = isEnabled;
|
this._mouseEvents = isEnabled;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
isMouseEventsEnabled: function () {
|
isMouseEventsEnabled() {
|
||||||
return this._mouseEvents;
|
return this._mouseEvents;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @return {Object<Number>} size*/
|
/** @return {Object<Number>} size */
|
||||||
getSize: function () {
|
getSize() {
|
||||||
return this._size;
|
return this._size;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @param {Object<Number>} size*/
|
/** @param {Object<Number>} size */
|
||||||
setSize: function (size) {
|
setSize(size) {
|
||||||
this._size.width = parseInt(size.width);
|
this._size.width = parseInt(size.width);
|
||||||
this._size.height = parseInt(size.height);
|
this._size.height = parseInt(size.height);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {mindplot.model.NodeModel} the node model
|
* @return {mindplot.model.NodeModel} the node model
|
||||||
*/
|
*/
|
||||||
getModel: function () {
|
getModel() {
|
||||||
$assert(this._model, 'Model has not been initialized yet');
|
$assert(this._model, 'Model has not been initialized yet');
|
||||||
return this._model;
|
return this._model;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {mindplot.NodeModel} model the node model
|
* @param {mindplot.NodeModel} model the node model
|
||||||
* @throws will throw an error if model is null or undefined
|
* @throws will throw an error if model is null or undefined
|
||||||
*/
|
*/
|
||||||
setModel: function (model) {
|
setModel(model) {
|
||||||
$assert(model, 'Model can not be null');
|
$assert(model, 'Model can not be null');
|
||||||
this._model = model;
|
this._model = model;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getId: function () {
|
getId() {
|
||||||
return this._model.getId();
|
return this._model.getId();
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setOnFocus: function (focus) {
|
setOnFocus(focus) {
|
||||||
if (this._onFocus != focus) {
|
if (this._onFocus != focus) {
|
||||||
this._onFocus = focus;
|
this._onFocus = focus;
|
||||||
var outerShape = this.getOuterShape();
|
const outerShape = this.getOuterShape();
|
||||||
if (focus) {
|
if (focus) {
|
||||||
outerShape.setFill(Topic.OUTER_SHAPE_ATTRIBUTES_FOCUS.fillColor);
|
outerShape.setFill(Topic.OUTER_SHAPE_ATTRIBUTES_FOCUS.fillColor);
|
||||||
outerShape.setOpacity(1);
|
outerShape.setOpacity(1);
|
||||||
} else {
|
} else {
|
||||||
outerShape.setFill(Topic.OUTER_SHAPE_ATTRIBUTES.fillColor);
|
outerShape.setFill(Topic.OUTER_SHAPE_ATTRIBUTES.fillColor);
|
||||||
outerShape.setOpacity(0);
|
outerShape.setOpacity(0);
|
||||||
}
|
}
|
||||||
this.setCursor('move');
|
this.setCursor('move');
|
||||||
|
|
||||||
// In any case, always try to hide the editor ...
|
// In any case, always try to hide the editor ...
|
||||||
this.closeEditors();
|
this.closeEditors();
|
||||||
|
|
||||||
// Fire event ...
|
// Fire event ...
|
||||||
this.fireEvent(focus ? 'ontfocus' : 'ontblur', this);
|
this.fireEvent(focus ? 'ontfocus' : 'ontblur', this);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @return {Boolean} true if the node graph is on focus */
|
/** @return {Boolean} true if the node graph is on focus */
|
||||||
isOnFocus: function () {
|
isOnFocus() {
|
||||||
return this._onFocus;
|
return this._onFocus;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
dispose: function (workspace) {
|
dispose(workspace) {
|
||||||
this.setOnFocus(false);
|
this.setOnFocus(false);
|
||||||
workspace.removeChild(this);
|
workspace.removeChild(this);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
createDragNode: function (layoutManager) {
|
createDragNode(layoutManager) {
|
||||||
var dragShape = this._buildDragShape();
|
const dragShape = this._buildDragShape();
|
||||||
return new DragTopic(dragShape, this, layoutManager);
|
return new DragTopic(dragShape, this, layoutManager);
|
||||||
},
|
},
|
||||||
|
|
||||||
_buildDragShape: function () {
|
_buildDragShape() {
|
||||||
$assert(false, '_buildDragShape must be implemented by all nodes.');
|
$assert(false, '_buildDragShape must be implemented by all nodes.');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getPosition: function () {
|
getPosition() {
|
||||||
var model = this.getModel();
|
const model = this.getModel();
|
||||||
return model.getPosition();
|
return model.getPosition();
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -199,24 +199,24 @@ const NodeGraph = new Class(
|
|||||||
* @return {mindplot.CentralTopic|mindplot.MainTopic} the new topic
|
* @return {mindplot.CentralTopic|mindplot.MainTopic} the new topic
|
||||||
*/
|
*/
|
||||||
NodeGraph.create = function (nodeModel, options) {
|
NodeGraph.create = function (nodeModel, options) {
|
||||||
const CentralTopic = require('./CentralTopic').default;
|
const CentralTopic = require('./CentralTopic').default;
|
||||||
const MainTopic = require('./MainTopic').default;
|
const MainTopic = require('./MainTopic').default;
|
||||||
|
|
||||||
$assert(nodeModel, 'Model can not be null');
|
$assert(nodeModel, 'Model can not be null');
|
||||||
|
|
||||||
var type = nodeModel.getType();
|
const type = nodeModel.getType();
|
||||||
$assert(type, 'Node model type can not be null');
|
$assert(type, 'Node model type can not be null');
|
||||||
|
|
||||||
var result;
|
let result;
|
||||||
if (type == INodeModel.CENTRAL_TOPIC_TYPE) {
|
if (type == INodeModel.CENTRAL_TOPIC_TYPE) {
|
||||||
result = new CentralTopic(nodeModel, options);
|
result = new CentralTopic(nodeModel, options);
|
||||||
} else if (type == INodeModel.MAIN_TOPIC_TYPE) {
|
} else if (type == INodeModel.MAIN_TOPIC_TYPE) {
|
||||||
result = new MainTopic(nodeModel, options);
|
result = new MainTopic(nodeModel, options);
|
||||||
} else {
|
} else {
|
||||||
$assert(false, 'unsupported node type:' + type);
|
$assert(false, `unsupported node type:${type}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default NodeGraph;
|
export default NodeGraph;
|
||||||
|
@ -19,66 +19,64 @@ const Icon = require('./Icon').default;
|
|||||||
const FloatingTip = require('./widget/FloatingTip').default;
|
const FloatingTip = require('./widget/FloatingTip').default;
|
||||||
|
|
||||||
const NoteIcon = new Class({
|
const NoteIcon = new Class({
|
||||||
Extends: Icon,
|
Extends: Icon,
|
||||||
initialize: function (topic, noteModel, readOnly) {
|
initialize(topic, noteModel, readOnly) {
|
||||||
$assert(topic, 'topic can not be null');
|
$assert(topic, 'topic can not be null');
|
||||||
|
|
||||||
this.parent(NoteIcon.IMAGE_URL);
|
this.parent(NoteIcon.IMAGE_URL);
|
||||||
this._linksModel = noteModel;
|
this._linksModel = noteModel;
|
||||||
this._topic = topic;
|
this._topic = topic;
|
||||||
this._readOnly = readOnly;
|
this._readOnly = readOnly;
|
||||||
|
|
||||||
this._registerEvents();
|
this._registerEvents();
|
||||||
},
|
},
|
||||||
|
|
||||||
_registerEvents: function () {
|
_registerEvents() {
|
||||||
this._image.setCursor('pointer');
|
this._image.setCursor('pointer');
|
||||||
var me = this;
|
const me = this;
|
||||||
|
|
||||||
if (!this._readOnly) {
|
if (!this._readOnly) {
|
||||||
// Add on click event to open the editor ...
|
// Add on click event to open the editor ...
|
||||||
this.addEvent('click', function (event) {
|
this.addEvent('click', (event) => {
|
||||||
me._topic.showNoteEditor();
|
me._topic.showNoteEditor();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
});
|
});
|
||||||
}
|
|
||||||
this._tip = new FloatingTip($(me.getImage()._peer._native), {
|
|
||||||
title: $msg('NOTE'),
|
|
||||||
container: 'body',
|
|
||||||
// Content can also be a function of the target element!
|
|
||||||
content: function () {
|
|
||||||
return me._buildTooltipContent();
|
|
||||||
},
|
|
||||||
html: true,
|
|
||||||
placement: 'bottom',
|
|
||||||
destroyOnExit: true
|
|
||||||
});
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
_buildTooltipContent: function () {
|
|
||||||
if ($("body").find("#textPopoverNote").length == 1) {
|
|
||||||
var text = $("body").find("#textPopoverNote");
|
|
||||||
text.text(this._linksModel.getText());
|
|
||||||
} else {
|
|
||||||
var result = $('<div id="textPopoverNote"></div>').css({padding: '5px'});
|
|
||||||
|
|
||||||
var text = $('<div></div>').text(this._linksModel.getText())
|
|
||||||
.css({
|
|
||||||
'white-space': 'pre-wrap',
|
|
||||||
'word-wrap': 'break-word'
|
|
||||||
}
|
|
||||||
);
|
|
||||||
result.append(text);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
getModel: function () {
|
|
||||||
return this._linksModel;
|
|
||||||
}
|
}
|
||||||
|
this._tip = new FloatingTip($(me.getImage()._peer._native), {
|
||||||
|
title: $msg('NOTE'),
|
||||||
|
container: 'body',
|
||||||
|
// Content can also be a function of the target element!
|
||||||
|
content() {
|
||||||
|
return me._buildTooltipContent();
|
||||||
|
},
|
||||||
|
html: true,
|
||||||
|
placement: 'bottom',
|
||||||
|
destroyOnExit: true,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_buildTooltipContent() {
|
||||||
|
if ($('body').find('#textPopoverNote').length == 1) {
|
||||||
|
var text = $('body').find('#textPopoverNote');
|
||||||
|
text.text(this._linksModel.getText());
|
||||||
|
} else {
|
||||||
|
const result = $('<div id="textPopoverNote"></div>').css({ padding: '5px' });
|
||||||
|
|
||||||
|
var text = $('<div></div>').text(this._linksModel.getText())
|
||||||
|
.css({
|
||||||
|
'white-space': 'pre-wrap',
|
||||||
|
'word-wrap': 'break-word',
|
||||||
|
});
|
||||||
|
result.append(text);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getModel() {
|
||||||
|
return this._linksModel;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
NoteIcon.IMAGE_URL = "images/notes.png";
|
NoteIcon.IMAGE_URL = 'images/notes.png';
|
||||||
|
|
||||||
export default NoteIcon
|
export default NoteIcon;
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
const Options = new Class({
|
const Options = new Class({
|
||||||
|
|
||||||
setOptions: function () {
|
setOptions() {
|
||||||
var options = this.options = Object.merge.apply(null, [{}, this.options].append(arguments));
|
const options = this.options = Object.merge.apply(null, [{}, this.options].append(arguments));
|
||||||
if (this.addEvent) for (var option in options) {
|
if (this.addEvent) {
|
||||||
if (typeOf(options[option]) != 'function' || !(/^on[A-Z]/).test(option)) continue;
|
for (const option in options) {
|
||||||
this.addEvent(option, options[option]);
|
if (typeOf(options[option]) != 'function' || !(/^on[A-Z]/).test(option)) continue;
|
||||||
delete options[option];
|
this.addEvent(option, options[option]);
|
||||||
}
|
delete options[option];
|
||||||
return this;
|
}
|
||||||
}
|
}
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -16,71 +16,72 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
const Core = require('@wismapping/core-js');
|
const Core = require('@wismapping/core-js');
|
||||||
|
|
||||||
const core = Core();
|
const core = Core();
|
||||||
const XMLSerializerFactory = require('./persistence/XMLSerializerFactory');
|
const XMLSerializerFactory = require('./persistence/XMLSerializerFactory');
|
||||||
|
|
||||||
const PersistenceManager = new Class({
|
const PersistenceManager = new Class({
|
||||||
Static: {
|
Static: {
|
||||||
loadFromDom: function (mapId, mapDom) {
|
loadFromDom(mapId, mapDom) {
|
||||||
$assert(mapId, 'mapId can not be null');
|
$assert(mapId, 'mapId can not be null');
|
||||||
$assert(mapDom, 'mapDom can not be null');
|
$assert(mapDom, 'mapDom can not be null');
|
||||||
|
|
||||||
var serializer = XMLSerializerFactory.getSerializerFromDocument(mapDom);
|
const serializer = XMLSerializerFactory.getSerializerFromDocument(mapDom);
|
||||||
return serializer.loadFromDom(mapDom, mapId);
|
return serializer.loadFromDom(mapDom, mapId);
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
|
||||||
initialize: function () {},
|
initialize() {},
|
||||||
|
|
||||||
save: function (mindmap, editorProperties, saveHistory, events, sync) {
|
save(mindmap, editorProperties, saveHistory, events, sync) {
|
||||||
$assert(mindmap, 'mindmap can not be null');
|
$assert(mindmap, 'mindmap can not be null');
|
||||||
$assert(editorProperties, 'editorProperties can not be null');
|
$assert(editorProperties, 'editorProperties can not be null');
|
||||||
|
|
||||||
var mapId = mindmap.getId();
|
const mapId = mindmap.getId();
|
||||||
$assert(mapId, 'mapId can not be null');
|
$assert(mapId, 'mapId can not be null');
|
||||||
|
|
||||||
var serializer = XMLSerializerFactory.getSerializerFromMindmap(mindmap);
|
const serializer = XMLSerializerFactory.getSerializerFromMindmap(mindmap);
|
||||||
var domMap = serializer.toXML(mindmap);
|
const domMap = serializer.toXML(mindmap);
|
||||||
var mapXml = core.Utils.innerXML(domMap);
|
const mapXml = core.Utils.innerXML(domMap);
|
||||||
|
|
||||||
var pref = JSON.stringify(editorProperties);
|
const pref = JSON.stringify(editorProperties);
|
||||||
try {
|
try {
|
||||||
this.saveMapXml(mapId, mapXml, pref, saveHistory, events, sync);
|
this.saveMapXml(mapId, mapXml, pref, saveHistory, events, sync);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(e);
|
console.log(e);
|
||||||
events.onError(this._buildError());
|
events.onError(this._buildError());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
load: function (mapId) {
|
load(mapId) {
|
||||||
$assert(mapId, 'mapId can not be null');
|
$assert(mapId, 'mapId can not be null');
|
||||||
var domDocument = this.loadMapDom(mapId);
|
const domDocument = this.loadMapDom(mapId);
|
||||||
return PersistenceManager.loadFromDom(mapId, domDocument);
|
return PersistenceManager.loadFromDom(mapId, domDocument);
|
||||||
},
|
},
|
||||||
|
|
||||||
discardChanges: function (mapId) {
|
discardChanges(mapId) {
|
||||||
throw new Error('Method must be implemented');
|
throw new Error('Method must be implemented');
|
||||||
},
|
},
|
||||||
|
|
||||||
loadMapDom: function (mapId) {
|
loadMapDom(mapId) {
|
||||||
throw new Error('Method must be implemented');
|
throw new Error('Method must be implemented');
|
||||||
},
|
},
|
||||||
|
|
||||||
saveMapXml: function (mapId, mapXml, pref, saveHistory, events, sync) {
|
saveMapXml(mapId, mapXml, pref, saveHistory, events, sync) {
|
||||||
throw new Error('Method must be implemented');
|
throw new Error('Method must be implemented');
|
||||||
},
|
},
|
||||||
|
|
||||||
unlockMap: function (mindmap) {
|
unlockMap(mindmap) {
|
||||||
throw new Error('Method must be implemented');
|
throw new Error('Method must be implemented');
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
PersistenceManager.init = function (instance) {
|
PersistenceManager.init = function (instance) {
|
||||||
PersistenceManager._instance = instance;
|
PersistenceManager._instance = instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
PersistenceManager.getInstance = function () {
|
PersistenceManager.getInstance = function () {
|
||||||
return PersistenceManager._instance;
|
return PersistenceManager._instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default PersistenceManager;
|
export default PersistenceManager;
|
||||||
|
@ -15,10 +15,12 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
const Core = require('@wismapping/core-js')
|
const Core = require('@wismapping/core-js');
|
||||||
|
|
||||||
const core = Core();
|
const core = Core();
|
||||||
|
|
||||||
const web2D = require('@wismapping/web2d')
|
const web2D = require('@wismapping/web2d');
|
||||||
|
|
||||||
const web2d = web2D();
|
const web2d = web2D();
|
||||||
|
|
||||||
const ConnectionLine = require('./ConnectionLine').default;
|
const ConnectionLine = require('./ConnectionLine').default;
|
||||||
@ -26,320 +28,310 @@ const ControlPoint = require('./ControlPoint').default;
|
|||||||
|
|
||||||
const INodeModel = require('./model/INodeModel').default;
|
const INodeModel = require('./model/INodeModel').default;
|
||||||
|
|
||||||
const Shape = require('./util/Shape').default
|
const Shape = require('./util/Shape').default;
|
||||||
|
|
||||||
const Relationship = new Class({
|
const Relationship = new Class({
|
||||||
Extends: ConnectionLine,
|
Extends: ConnectionLine,
|
||||||
Static: {
|
Static: {
|
||||||
getStrokeColor: function () {
|
getStrokeColor() {
|
||||||
return '#9b74e6';
|
return '#9b74e6';
|
||||||
},
|
|
||||||
type: "Relationship"
|
|
||||||
},
|
},
|
||||||
initialize: function (sourceNode, targetNode, model) {
|
type: 'Relationship',
|
||||||
$assert(sourceNode, "sourceNode can not be null");
|
},
|
||||||
$assert(targetNode, "targetNode can not be null");
|
initialize(sourceNode, targetNode, model) {
|
||||||
|
$assert(sourceNode, 'sourceNode can not be null');
|
||||||
|
$assert(targetNode, 'targetNode can not be null');
|
||||||
|
|
||||||
this.parent(sourceNode, targetNode, model.getLineType());
|
this.parent(sourceNode, targetNode, model.getLineType());
|
||||||
this.setModel(model);
|
this.setModel(model);
|
||||||
|
|
||||||
var strokeColor = Relationship.getStrokeColor();
|
const strokeColor = Relationship.getStrokeColor();
|
||||||
|
|
||||||
this._line2d.setIsSrcControlPointCustom(false);
|
this._line2d.setIsSrcControlPointCustom(false);
|
||||||
this._line2d.setIsDestControlPointCustom(false);
|
this._line2d.setIsDestControlPointCustom(false);
|
||||||
this._line2d.setCursor('pointer');
|
this._line2d.setCursor('pointer');
|
||||||
this._line2d.setStroke(1, 'solid', strokeColor);
|
this._line2d.setStroke(1, 'solid', strokeColor);
|
||||||
this._line2d.setDashed(4, 2);
|
this._line2d.setDashed(4, 2);
|
||||||
this._focusShape = this._createLine(this.getLineType(), ConnectionLine.SIMPLE_CURVED);
|
this._focusShape = this._createLine(this.getLineType(), ConnectionLine.SIMPLE_CURVED);
|
||||||
this._focusShape.setStroke(2, "solid", "#3f96ff");
|
this._focusShape.setStroke(2, 'solid', '#3f96ff');
|
||||||
|
|
||||||
var ctrlPoints = this._line2d.getControlPoints();
|
const ctrlPoints = this._line2d.getControlPoints();
|
||||||
this._focusShape.setSrcControlPoint(ctrlPoints[0]);
|
this._focusShape.setSrcControlPoint(ctrlPoints[0]);
|
||||||
this._focusShape.setDestControlPoint(ctrlPoints[1]);
|
this._focusShape.setDestControlPoint(ctrlPoints[1]);
|
||||||
this._focusShape.setVisibility(false);
|
this._focusShape.setVisibility(false);
|
||||||
this._onFocus = false;
|
this._onFocus = false;
|
||||||
this._isInWorkspace = false;
|
this._isInWorkspace = false;
|
||||||
this._controlPointsController = new ControlPoint();
|
this._controlPointsController = new ControlPoint();
|
||||||
|
|
||||||
this._startArrow = new web2d.Arrow();
|
this._startArrow = new web2d.Arrow();
|
||||||
this._startArrow.setStrokeColor(strokeColor);
|
this._startArrow.setStrokeColor(strokeColor);
|
||||||
this._startArrow.setStrokeWidth(2);
|
this._startArrow.setStrokeWidth(2);
|
||||||
this.setShowStartArrow(true);
|
this.setShowStartArrow(true);
|
||||||
|
|
||||||
// Share style is disable ...
|
// Share style is disable ...
|
||||||
if (this._showEndArrow) {
|
if (this._showEndArrow) {
|
||||||
this._endArrow = new web2d.Arrow();
|
this._endArrow = new web2d.Arrow();
|
||||||
this._endArrow.setStrokeColor(strokeColor);
|
this._endArrow.setStrokeColor(strokeColor);
|
||||||
this._endArrow.setStrokeWidth(2);
|
this._endArrow.setStrokeWidth(2);
|
||||||
}
|
|
||||||
|
|
||||||
// Position the line ...
|
|
||||||
if ($defined(model.getSrcCtrlPoint())) {
|
|
||||||
var srcPoint = model.getSrcCtrlPoint().clone();
|
|
||||||
this.setSrcControlPoint(srcPoint);
|
|
||||||
}
|
|
||||||
if ($defined(model.getDestCtrlPoint())) {
|
|
||||||
var destPoint = model.getDestCtrlPoint().clone();
|
|
||||||
this.setDestControlPoint(destPoint);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
setStroke: function (color, style, opacity) {
|
|
||||||
this.parent(color, style, opacity);
|
|
||||||
this._startArrow.setStrokeColor(color);
|
|
||||||
},
|
|
||||||
|
|
||||||
redraw: function () {
|
|
||||||
var line2d = this._line2d;
|
|
||||||
var sourceTopic = this._sourceTopic;
|
|
||||||
var sourcePosition = sourceTopic.getPosition();
|
|
||||||
|
|
||||||
var targetTopic = this._targetTopic;
|
|
||||||
var targetPosition = targetTopic.getPosition();
|
|
||||||
if (targetTopic.getType() == INodeModel.CENTRAL_TOPIC_TYPE) {
|
|
||||||
targetPosition = Shape.workoutIncomingConnectionPoint(targetTopic, sourcePosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
var sPos, tPos;
|
|
||||||
this._line2d.setStroke(2);
|
|
||||||
var ctrlPoints = this._line2d.getControlPoints();
|
|
||||||
if (!this._line2d.isDestControlPointCustom() && !this._line2d.isSrcControlPointCustom()) {
|
|
||||||
|
|
||||||
var defaultPoints = Shape.calculateDefaultControlPoints(sourcePosition, targetPosition);
|
|
||||||
ctrlPoints[0].x = defaultPoints[0].x;
|
|
||||||
ctrlPoints[0].y = defaultPoints[0].y;
|
|
||||||
|
|
||||||
ctrlPoints[1].x = defaultPoints[1].x;
|
|
||||||
ctrlPoints[1].y = defaultPoints[1].y;
|
|
||||||
}
|
|
||||||
var spoint = new core.Point();
|
|
||||||
spoint.x = parseInt(ctrlPoints[0].x) + parseInt(sourcePosition.x);
|
|
||||||
spoint.y = parseInt(ctrlPoints[0].y) + parseInt(sourcePosition.y);
|
|
||||||
|
|
||||||
var tpoint = new core.Point();
|
|
||||||
tpoint.x = parseInt(ctrlPoints[1].x) + parseInt(targetPosition.x);
|
|
||||||
tpoint.y = parseInt(ctrlPoints[1].y) + parseInt(targetPosition.y);
|
|
||||||
|
|
||||||
sPos = Shape.calculateRelationShipPointCoordinates(sourceTopic, spoint);
|
|
||||||
tPos = Shape.calculateRelationShipPointCoordinates(targetTopic, tpoint);
|
|
||||||
|
|
||||||
line2d.setFrom(sPos.x, sPos.y);
|
|
||||||
line2d.setTo(tPos.x, tPos.y);
|
|
||||||
|
|
||||||
line2d.moveToFront();
|
|
||||||
|
|
||||||
//Positionate Arrows
|
|
||||||
this._positionArrows();
|
|
||||||
|
|
||||||
// Add connector ...
|
|
||||||
this._positionateConnector(targetTopic);
|
|
||||||
|
|
||||||
if (this.isOnFocus()) {
|
|
||||||
this._refreshShape();
|
|
||||||
}
|
|
||||||
this._focusShape.moveToBack();
|
|
||||||
this._controlPointsController.redraw();
|
|
||||||
},
|
|
||||||
|
|
||||||
_positionArrows: function () {
|
|
||||||
var tpos = this._line2d.getTo();
|
|
||||||
var spos = this._line2d.getFrom();
|
|
||||||
|
|
||||||
this._startArrow.setFrom(spos.x, spos.y);
|
|
||||||
this._startArrow.moveToBack();
|
|
||||||
|
|
||||||
if (this._endArrow) {
|
|
||||||
this._endArrow.setFrom(tpos.x, tpos.y);
|
|
||||||
this._endArrow.moveToBack();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._line2d.getType() == "CurvedLine") {
|
|
||||||
var controlPoints = this._line2d.getControlPoints();
|
|
||||||
this._startArrow.setControlPoint(controlPoints[0]);
|
|
||||||
if (this._endArrow) {
|
|
||||||
this._endArrow.setControlPoint(controlPoints[1]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this._startArrow.setControlPoint(this._line2d.getTo());
|
|
||||||
if (this._endArrow) {
|
|
||||||
this._endArrow.setControlPoint(this._line2d.getFrom());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._showEndArrow) {
|
|
||||||
this._endArrow.setVisibility(this.isVisible());
|
|
||||||
}
|
|
||||||
this._startArrow.setVisibility(this.isVisible() && this._showStartArrow);
|
|
||||||
},
|
|
||||||
|
|
||||||
addToWorkspace: function (workspace) {
|
|
||||||
workspace.append(this._focusShape);
|
|
||||||
workspace.append(this._controlPointsController);
|
|
||||||
|
|
||||||
this._controlPointControllerListener = this._initializeControlPointController.bind(this);
|
|
||||||
this._line2d.addEvent('click', this._controlPointControllerListener);
|
|
||||||
this._isInWorkspace = true;
|
|
||||||
|
|
||||||
workspace.append(this._startArrow);
|
|
||||||
if (this._endArrow)
|
|
||||||
workspace.append(this._endArrow);
|
|
||||||
|
|
||||||
this.parent(workspace);
|
|
||||||
this._positionArrows();
|
|
||||||
this.redraw();
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
_initializeControlPointController: function () {
|
|
||||||
this.setOnFocus(true);
|
|
||||||
},
|
|
||||||
|
|
||||||
removeFromWorkspace: function (workspace) {
|
|
||||||
workspace.removeChild(this._focusShape);
|
|
||||||
workspace.removeChild(this._controlPointsController);
|
|
||||||
this._line2d.removeEvent('click', this._controlPointControllerListener);
|
|
||||||
this._isInWorkspace = false;
|
|
||||||
workspace.removeChild(this._startArrow);
|
|
||||||
if (this._endArrow)
|
|
||||||
workspace.removeChild(this._endArrow);
|
|
||||||
|
|
||||||
this.parent(workspace);
|
|
||||||
},
|
|
||||||
|
|
||||||
getType: function () {
|
|
||||||
return Relationship.type;
|
|
||||||
},
|
|
||||||
|
|
||||||
setOnFocus: function (focus) {
|
|
||||||
// Change focus shape
|
|
||||||
if (this.isOnFocus() != focus) {
|
|
||||||
if (focus) {
|
|
||||||
this._refreshShape();
|
|
||||||
this._controlPointsController.setLine(this);
|
|
||||||
}
|
|
||||||
this._focusShape.setVisibility(focus);
|
|
||||||
|
|
||||||
this._controlPointsController.setVisibility(focus);
|
|
||||||
this._onFocus = focus;
|
|
||||||
this.fireEvent(focus ? 'ontfocus' : 'ontblur', this);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_refreshShape: function () {
|
|
||||||
var sPos = this._line2d.getFrom();
|
|
||||||
var tPos = this._line2d.getTo();
|
|
||||||
var ctrlPoints = this._line2d.getControlPoints();
|
|
||||||
this._focusShape.setFrom(sPos.x, sPos.y);
|
|
||||||
this._focusShape.setTo(tPos.x, tPos.y);
|
|
||||||
var shapeCtrlPoints = this._focusShape.getControlPoints();
|
|
||||||
shapeCtrlPoints[0].x = ctrlPoints[0].x;
|
|
||||||
shapeCtrlPoints[0].y = ctrlPoints[0].y;
|
|
||||||
shapeCtrlPoints[1].x = ctrlPoints[1].x;
|
|
||||||
shapeCtrlPoints[1].y = ctrlPoints[1].y;
|
|
||||||
this._focusShape.updateLine();
|
|
||||||
},
|
|
||||||
|
|
||||||
addEvent: function (type, listener) {
|
|
||||||
// Translate to web 2d events ...
|
|
||||||
if (type == 'onfocus') {
|
|
||||||
type = 'mousedown';
|
|
||||||
}
|
|
||||||
|
|
||||||
var line = this._line2d;
|
|
||||||
line.addEvent(type, listener);
|
|
||||||
},
|
|
||||||
|
|
||||||
isOnFocus: function () {
|
|
||||||
return this._onFocus;
|
|
||||||
},
|
|
||||||
|
|
||||||
isInWorkspace: function () {
|
|
||||||
return this._isInWorkspace;
|
|
||||||
},
|
|
||||||
|
|
||||||
setVisibility: function (value) {
|
|
||||||
this.parent(value);
|
|
||||||
if (this._showEndArrow)
|
|
||||||
this._endArrow.setVisibility(this._showEndArrow);
|
|
||||||
this._startArrow.setVisibility(this._showStartArrow && value);
|
|
||||||
},
|
|
||||||
|
|
||||||
setOpacity: function (opacity) {
|
|
||||||
this.parent(opacity);
|
|
||||||
if (this._showEndArrow)
|
|
||||||
this._endArrow.setOpacity(opacity);
|
|
||||||
if (this._showStartArrow)
|
|
||||||
this._startArrow.setOpacity(opacity);
|
|
||||||
},
|
|
||||||
|
|
||||||
setShowEndArrow: function (visible) {
|
|
||||||
this._showEndArrow = visible;
|
|
||||||
if (this._isInWorkspace)
|
|
||||||
this.redraw();
|
|
||||||
},
|
|
||||||
|
|
||||||
setShowStartArrow: function (visible) {
|
|
||||||
this._showStartArrow = visible;
|
|
||||||
if (this._isInWorkspace)
|
|
||||||
this.redraw();
|
|
||||||
},
|
|
||||||
|
|
||||||
setFrom: function (x, y) {
|
|
||||||
$assert($defined(x), "x must be defined");
|
|
||||||
$assert($defined(y), "y must be defined");
|
|
||||||
|
|
||||||
this._line2d.setFrom(x, y);
|
|
||||||
this._startArrow.setFrom(x, y);
|
|
||||||
},
|
|
||||||
|
|
||||||
setTo: function (x, y) {
|
|
||||||
$assert($defined(x), "x must be defined");
|
|
||||||
$assert($defined(y), "y must be defined");
|
|
||||||
|
|
||||||
this._line2d.setTo(x, y);
|
|
||||||
if (this._endArrow)
|
|
||||||
this._endArrow.setFrom(x, y);
|
|
||||||
},
|
|
||||||
|
|
||||||
setSrcControlPoint: function (control) {
|
|
||||||
this._line2d.setSrcControlPoint(control);
|
|
||||||
this._startArrow.setControlPoint(control);
|
|
||||||
},
|
|
||||||
|
|
||||||
setDestControlPoint: function (control) {
|
|
||||||
this._line2d.setDestControlPoint(control);
|
|
||||||
if (this._showEndArrow)
|
|
||||||
this._endArrow.setControlPoint(control);
|
|
||||||
},
|
|
||||||
|
|
||||||
getControlPoints: function () {
|
|
||||||
return this._line2d.getControlPoints();
|
|
||||||
},
|
|
||||||
|
|
||||||
isSrcControlPointCustom: function () {
|
|
||||||
return this._line2d.isSrcControlPointCustom();
|
|
||||||
},
|
|
||||||
|
|
||||||
isDestControlPointCustom: function () {
|
|
||||||
return this._line2d.isDestControlPointCustom();
|
|
||||||
},
|
|
||||||
|
|
||||||
setIsSrcControlPointCustom: function (isCustom) {
|
|
||||||
this._line2d.setIsSrcControlPointCustom(isCustom);
|
|
||||||
},
|
|
||||||
|
|
||||||
setIsDestControlPointCustom: function (isCustom) {
|
|
||||||
this._line2d.setIsDestControlPointCustom(isCustom);
|
|
||||||
},
|
|
||||||
|
|
||||||
getId: function () {
|
|
||||||
return this._model.getId();
|
|
||||||
},
|
|
||||||
|
|
||||||
fireEvent: function (type, event) {
|
|
||||||
var elem = this._line2d;
|
|
||||||
elem.trigger(type, event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Position the line ...
|
||||||
|
if ($defined(model.getSrcCtrlPoint())) {
|
||||||
|
const srcPoint = model.getSrcCtrlPoint().clone();
|
||||||
|
this.setSrcControlPoint(srcPoint);
|
||||||
|
}
|
||||||
|
if ($defined(model.getDestCtrlPoint())) {
|
||||||
|
const destPoint = model.getDestCtrlPoint().clone();
|
||||||
|
this.setDestControlPoint(destPoint);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setStroke(color, style, opacity) {
|
||||||
|
this.parent(color, style, opacity);
|
||||||
|
this._startArrow.setStrokeColor(color);
|
||||||
|
},
|
||||||
|
|
||||||
|
redraw() {
|
||||||
|
const line2d = this._line2d;
|
||||||
|
const sourceTopic = this._sourceTopic;
|
||||||
|
const sourcePosition = sourceTopic.getPosition();
|
||||||
|
|
||||||
|
const targetTopic = this._targetTopic;
|
||||||
|
let targetPosition = targetTopic.getPosition();
|
||||||
|
if (targetTopic.getType() == INodeModel.CENTRAL_TOPIC_TYPE) {
|
||||||
|
targetPosition = Shape.workoutIncomingConnectionPoint(targetTopic, sourcePosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
let sPos; let
|
||||||
|
tPos;
|
||||||
|
this._line2d.setStroke(2);
|
||||||
|
const ctrlPoints = this._line2d.getControlPoints();
|
||||||
|
if (!this._line2d.isDestControlPointCustom() && !this._line2d.isSrcControlPointCustom()) {
|
||||||
|
const defaultPoints = Shape.calculateDefaultControlPoints(sourcePosition, targetPosition);
|
||||||
|
ctrlPoints[0].x = defaultPoints[0].x;
|
||||||
|
ctrlPoints[0].y = defaultPoints[0].y;
|
||||||
|
|
||||||
|
ctrlPoints[1].x = defaultPoints[1].x;
|
||||||
|
ctrlPoints[1].y = defaultPoints[1].y;
|
||||||
|
}
|
||||||
|
const spoint = new core.Point();
|
||||||
|
spoint.x = parseInt(ctrlPoints[0].x) + parseInt(sourcePosition.x);
|
||||||
|
spoint.y = parseInt(ctrlPoints[0].y) + parseInt(sourcePosition.y);
|
||||||
|
|
||||||
|
const tpoint = new core.Point();
|
||||||
|
tpoint.x = parseInt(ctrlPoints[1].x) + parseInt(targetPosition.x);
|
||||||
|
tpoint.y = parseInt(ctrlPoints[1].y) + parseInt(targetPosition.y);
|
||||||
|
|
||||||
|
sPos = Shape.calculateRelationShipPointCoordinates(sourceTopic, spoint);
|
||||||
|
tPos = Shape.calculateRelationShipPointCoordinates(targetTopic, tpoint);
|
||||||
|
|
||||||
|
line2d.setFrom(sPos.x, sPos.y);
|
||||||
|
line2d.setTo(tPos.x, tPos.y);
|
||||||
|
|
||||||
|
line2d.moveToFront();
|
||||||
|
|
||||||
|
// Positionate Arrows
|
||||||
|
this._positionArrows();
|
||||||
|
|
||||||
|
// Add connector ...
|
||||||
|
this._positionateConnector(targetTopic);
|
||||||
|
|
||||||
|
if (this.isOnFocus()) {
|
||||||
|
this._refreshShape();
|
||||||
|
}
|
||||||
|
this._focusShape.moveToBack();
|
||||||
|
this._controlPointsController.redraw();
|
||||||
|
},
|
||||||
|
|
||||||
|
_positionArrows() {
|
||||||
|
const tpos = this._line2d.getTo();
|
||||||
|
const spos = this._line2d.getFrom();
|
||||||
|
|
||||||
|
this._startArrow.setFrom(spos.x, spos.y);
|
||||||
|
this._startArrow.moveToBack();
|
||||||
|
|
||||||
|
if (this._endArrow) {
|
||||||
|
this._endArrow.setFrom(tpos.x, tpos.y);
|
||||||
|
this._endArrow.moveToBack();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._line2d.getType() == 'CurvedLine') {
|
||||||
|
const controlPoints = this._line2d.getControlPoints();
|
||||||
|
this._startArrow.setControlPoint(controlPoints[0]);
|
||||||
|
if (this._endArrow) {
|
||||||
|
this._endArrow.setControlPoint(controlPoints[1]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this._startArrow.setControlPoint(this._line2d.getTo());
|
||||||
|
if (this._endArrow) {
|
||||||
|
this._endArrow.setControlPoint(this._line2d.getFrom());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._showEndArrow) {
|
||||||
|
this._endArrow.setVisibility(this.isVisible());
|
||||||
|
}
|
||||||
|
this._startArrow.setVisibility(this.isVisible() && this._showStartArrow);
|
||||||
|
},
|
||||||
|
|
||||||
|
addToWorkspace(workspace) {
|
||||||
|
workspace.append(this._focusShape);
|
||||||
|
workspace.append(this._controlPointsController);
|
||||||
|
|
||||||
|
this._controlPointControllerListener = this._initializeControlPointController.bind(this);
|
||||||
|
this._line2d.addEvent('click', this._controlPointControllerListener);
|
||||||
|
this._isInWorkspace = true;
|
||||||
|
|
||||||
|
workspace.append(this._startArrow);
|
||||||
|
if (this._endArrow) workspace.append(this._endArrow);
|
||||||
|
|
||||||
|
this.parent(workspace);
|
||||||
|
this._positionArrows();
|
||||||
|
this.redraw();
|
||||||
|
},
|
||||||
|
|
||||||
|
_initializeControlPointController() {
|
||||||
|
this.setOnFocus(true);
|
||||||
|
},
|
||||||
|
|
||||||
|
removeFromWorkspace(workspace) {
|
||||||
|
workspace.removeChild(this._focusShape);
|
||||||
|
workspace.removeChild(this._controlPointsController);
|
||||||
|
this._line2d.removeEvent('click', this._controlPointControllerListener);
|
||||||
|
this._isInWorkspace = false;
|
||||||
|
workspace.removeChild(this._startArrow);
|
||||||
|
if (this._endArrow) workspace.removeChild(this._endArrow);
|
||||||
|
|
||||||
|
this.parent(workspace);
|
||||||
|
},
|
||||||
|
|
||||||
|
getType() {
|
||||||
|
return Relationship.type;
|
||||||
|
},
|
||||||
|
|
||||||
|
setOnFocus(focus) {
|
||||||
|
// Change focus shape
|
||||||
|
if (this.isOnFocus() != focus) {
|
||||||
|
if (focus) {
|
||||||
|
this._refreshShape();
|
||||||
|
this._controlPointsController.setLine(this);
|
||||||
|
}
|
||||||
|
this._focusShape.setVisibility(focus);
|
||||||
|
|
||||||
|
this._controlPointsController.setVisibility(focus);
|
||||||
|
this._onFocus = focus;
|
||||||
|
this.fireEvent(focus ? 'ontfocus' : 'ontblur', this);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_refreshShape() {
|
||||||
|
const sPos = this._line2d.getFrom();
|
||||||
|
const tPos = this._line2d.getTo();
|
||||||
|
const ctrlPoints = this._line2d.getControlPoints();
|
||||||
|
this._focusShape.setFrom(sPos.x, sPos.y);
|
||||||
|
this._focusShape.setTo(tPos.x, tPos.y);
|
||||||
|
const shapeCtrlPoints = this._focusShape.getControlPoints();
|
||||||
|
shapeCtrlPoints[0].x = ctrlPoints[0].x;
|
||||||
|
shapeCtrlPoints[0].y = ctrlPoints[0].y;
|
||||||
|
shapeCtrlPoints[1].x = ctrlPoints[1].x;
|
||||||
|
shapeCtrlPoints[1].y = ctrlPoints[1].y;
|
||||||
|
this._focusShape.updateLine();
|
||||||
|
},
|
||||||
|
|
||||||
|
addEvent(type, listener) {
|
||||||
|
// Translate to web 2d events ...
|
||||||
|
if (type == 'onfocus') {
|
||||||
|
type = 'mousedown';
|
||||||
|
}
|
||||||
|
|
||||||
|
const line = this._line2d;
|
||||||
|
line.addEvent(type, listener);
|
||||||
|
},
|
||||||
|
|
||||||
|
isOnFocus() {
|
||||||
|
return this._onFocus;
|
||||||
|
},
|
||||||
|
|
||||||
|
isInWorkspace() {
|
||||||
|
return this._isInWorkspace;
|
||||||
|
},
|
||||||
|
|
||||||
|
setVisibility(value) {
|
||||||
|
this.parent(value);
|
||||||
|
if (this._showEndArrow) this._endArrow.setVisibility(this._showEndArrow);
|
||||||
|
this._startArrow.setVisibility(this._showStartArrow && value);
|
||||||
|
},
|
||||||
|
|
||||||
|
setOpacity(opacity) {
|
||||||
|
this.parent(opacity);
|
||||||
|
if (this._showEndArrow) this._endArrow.setOpacity(opacity);
|
||||||
|
if (this._showStartArrow) this._startArrow.setOpacity(opacity);
|
||||||
|
},
|
||||||
|
|
||||||
|
setShowEndArrow(visible) {
|
||||||
|
this._showEndArrow = visible;
|
||||||
|
if (this._isInWorkspace) this.redraw();
|
||||||
|
},
|
||||||
|
|
||||||
|
setShowStartArrow(visible) {
|
||||||
|
this._showStartArrow = visible;
|
||||||
|
if (this._isInWorkspace) this.redraw();
|
||||||
|
},
|
||||||
|
|
||||||
|
setFrom(x, y) {
|
||||||
|
$assert($defined(x), 'x must be defined');
|
||||||
|
$assert($defined(y), 'y must be defined');
|
||||||
|
|
||||||
|
this._line2d.setFrom(x, y);
|
||||||
|
this._startArrow.setFrom(x, y);
|
||||||
|
},
|
||||||
|
|
||||||
|
setTo(x, y) {
|
||||||
|
$assert($defined(x), 'x must be defined');
|
||||||
|
$assert($defined(y), 'y must be defined');
|
||||||
|
|
||||||
|
this._line2d.setTo(x, y);
|
||||||
|
if (this._endArrow) this._endArrow.setFrom(x, y);
|
||||||
|
},
|
||||||
|
|
||||||
|
setSrcControlPoint(control) {
|
||||||
|
this._line2d.setSrcControlPoint(control);
|
||||||
|
this._startArrow.setControlPoint(control);
|
||||||
|
},
|
||||||
|
|
||||||
|
setDestControlPoint(control) {
|
||||||
|
this._line2d.setDestControlPoint(control);
|
||||||
|
if (this._showEndArrow) this._endArrow.setControlPoint(control);
|
||||||
|
},
|
||||||
|
|
||||||
|
getControlPoints() {
|
||||||
|
return this._line2d.getControlPoints();
|
||||||
|
},
|
||||||
|
|
||||||
|
isSrcControlPointCustom() {
|
||||||
|
return this._line2d.isSrcControlPointCustom();
|
||||||
|
},
|
||||||
|
|
||||||
|
isDestControlPointCustom() {
|
||||||
|
return this._line2d.isDestControlPointCustom();
|
||||||
|
},
|
||||||
|
|
||||||
|
setIsSrcControlPointCustom(isCustom) {
|
||||||
|
this._line2d.setIsSrcControlPointCustom(isCustom);
|
||||||
|
},
|
||||||
|
|
||||||
|
setIsDestControlPointCustom(isCustom) {
|
||||||
|
this._line2d.setIsDestControlPointCustom(isCustom);
|
||||||
|
},
|
||||||
|
|
||||||
|
getId() {
|
||||||
|
return this._model.getId();
|
||||||
|
},
|
||||||
|
|
||||||
|
fireEvent(type, event) {
|
||||||
|
const elem = this._line2d;
|
||||||
|
elem.trigger(type, event);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default Relationship;
|
export default Relationship;
|
||||||
|
@ -15,153 +15,151 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
const Core = require('@wismapping/core-js')
|
const Core = require('@wismapping/core-js');
|
||||||
|
|
||||||
const core = Core();
|
const core = Core();
|
||||||
const web2D = require('@wismapping/web2d')
|
const web2D = require('@wismapping/web2d');
|
||||||
|
|
||||||
const web2d = web2D();
|
const web2d = web2D();
|
||||||
const INodeModel = require('./model/INodeModel').default
|
const INodeModel = require('./model/INodeModel').default;
|
||||||
const Shape = require('./util/Shape').default;
|
const Shape = require('./util/Shape').default;
|
||||||
|
|
||||||
const RelationshipPivot = new Class({
|
const RelationshipPivot = new Class({
|
||||||
initialize: function (workspace, designer) {
|
initialize(workspace, designer) {
|
||||||
$assert(workspace, "workspace can not be null");
|
$assert(workspace, 'workspace can not be null');
|
||||||
$assert(designer, "designer can not be null");
|
$assert(designer, 'designer can not be null');
|
||||||
this._workspace = workspace;
|
this._workspace = workspace;
|
||||||
this._designer = designer;
|
this._designer = designer;
|
||||||
|
|
||||||
//FIXME: the aim of the migration is remove .bind mootools method, please remove these!
|
// FIXME: the aim of the migration is remove .bind mootools method, please remove these!
|
||||||
this._mouseMoveEvent = this._mouseMove.bind(this);
|
this._mouseMoveEvent = this._mouseMove.bind(this);
|
||||||
this._onClickEvent = this._cleanOnMouseClick.bind(this);
|
this._onClickEvent = this._cleanOnMouseClick.bind(this);
|
||||||
this._onTopicClick = this._connectOnFocus.bind(this);
|
this._onTopicClick = this._connectOnFocus.bind(this);
|
||||||
|
},
|
||||||
|
|
||||||
},
|
start(sourceTopic, targetPos) {
|
||||||
|
$assert(sourceTopic, 'sourceTopic can not be null');
|
||||||
|
$assert(targetPos, 'targetPos can not be null');
|
||||||
|
|
||||||
start: function (sourceTopic, targetPos) {
|
this.dispose();
|
||||||
$assert(sourceTopic, "sourceTopic can not be null");
|
this._sourceTopic = sourceTopic;
|
||||||
$assert(targetPos, "targetPos can not be null");
|
if (sourceTopic != null) {
|
||||||
|
this._workspace.enableWorkspaceEvents(false);
|
||||||
|
|
||||||
this.dispose();
|
const sourcePos = sourceTopic.getPosition();
|
||||||
this._sourceTopic = sourceTopic;
|
const strokeColor = Relationship.getStrokeColor();
|
||||||
if (sourceTopic != null) {
|
|
||||||
this._workspace.enableWorkspaceEvents(false);
|
|
||||||
|
|
||||||
var sourcePos = sourceTopic.getPosition();
|
this._pivot = new web2d.CurvedLine();
|
||||||
var strokeColor = Relationship.getStrokeColor();
|
this._pivot.setStyle(web2d.CurvedLine.SIMPLE_LINE);
|
||||||
|
|
||||||
this._pivot = new web2d.CurvedLine();
|
const fromPos = this._calculateFromPosition(sourcePos);
|
||||||
this._pivot.setStyle(web2d.CurvedLine.SIMPLE_LINE);
|
this._pivot.setFrom(fromPos.x, fromPos.y);
|
||||||
|
|
||||||
var fromPos = this._calculateFromPosition(sourcePos);
|
this._pivot.setTo(targetPos.x, targetPos.y);
|
||||||
this._pivot.setFrom(fromPos.x, fromPos.y);
|
this._pivot.setStroke(2, 'solid', strokeColor);
|
||||||
|
this._pivot.setDashed(4, 2);
|
||||||
|
|
||||||
this._pivot.setTo(targetPos.x, targetPos.y);
|
this._startArrow = new web2d.Arrow();
|
||||||
this._pivot.setStroke(2, 'solid', strokeColor);
|
this._startArrow.setStrokeColor(strokeColor);
|
||||||
this._pivot.setDashed(4, 2);
|
this._startArrow.setStrokeWidth(2);
|
||||||
|
this._startArrow.setFrom(sourcePos.x, sourcePos.y);
|
||||||
|
|
||||||
this._startArrow = new web2d.Arrow();
|
this._workspace.append(this._pivot);
|
||||||
this._startArrow.setStrokeColor(strokeColor);
|
this._workspace.append(this._startArrow);
|
||||||
this._startArrow.setStrokeWidth(2);
|
|
||||||
this._startArrow.setFrom(sourcePos.x, sourcePos.y);
|
|
||||||
|
|
||||||
this._workspace.append(this._pivot);
|
this._workspace.addEvent('mousemove', this._mouseMoveEvent);
|
||||||
this._workspace.append(this._startArrow);
|
this._workspace.addEvent('click', this._onClickEvent);
|
||||||
|
|
||||||
this._workspace.addEvent('mousemove', this._mouseMoveEvent);
|
// Register focus events on all topics ...
|
||||||
this._workspace.addEvent('click', this._onClickEvent);
|
const model = this._designer.getModel();
|
||||||
|
const topics = model.getTopics();
|
||||||
// Register focus events on all topics ...
|
_.each(topics, (topic) => {
|
||||||
var model = this._designer.getModel();
|
topic.addEvent('ontfocus', this._onTopicClick);
|
||||||
var topics = model.getTopics();
|
});
|
||||||
_.each(topics, function (topic) {
|
|
||||||
topic.addEvent('ontfocus', this._onTopicClick);
|
|
||||||
}.bind(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
dispose: function () {
|
|
||||||
var workspace = this._workspace;
|
|
||||||
|
|
||||||
if (this._isActive()) {
|
|
||||||
workspace.removeEvent('mousemove', this._mouseMoveEvent);
|
|
||||||
workspace.removeEvent('click', this._onClickEvent);
|
|
||||||
|
|
||||||
var model = this._designer.getModel();
|
|
||||||
var topics = model.getTopics();
|
|
||||||
var me = this;
|
|
||||||
_.each(topics, function (topic) {
|
|
||||||
topic.removeEvent('ontfocus', me._onTopicClick);
|
|
||||||
});
|
|
||||||
|
|
||||||
workspace.removeChild(this._pivot);
|
|
||||||
workspace.removeChild(this._startArrow);
|
|
||||||
workspace.enableWorkspaceEvents(true);
|
|
||||||
|
|
||||||
this._sourceTopic = null;
|
|
||||||
this._pivot = null;
|
|
||||||
this._startArrow = null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_mouseMove: function (event) {
|
|
||||||
var screen = this._workspace.getScreenManager();
|
|
||||||
var pos = screen.getWorkspaceMousePosition(event);
|
|
||||||
|
|
||||||
// Leave the arrow a couple of pixels away from the cursor.
|
|
||||||
var sourcePosition = this._sourceTopic.getPosition();
|
|
||||||
var gapDistance = Math.sign(pos.x - sourcePosition.x) * 5;
|
|
||||||
|
|
||||||
var sPos = this._calculateFromPosition(pos);
|
|
||||||
this._pivot.setFrom(sPos.x, sPos.y);
|
|
||||||
|
|
||||||
// Update target position ...
|
|
||||||
this._pivot.setTo(pos.x - gapDistance, pos.y);
|
|
||||||
|
|
||||||
var controlPoints = this._pivot.getControlPoints();
|
|
||||||
this._startArrow.setFrom(pos.x - gapDistance, pos.y);
|
|
||||||
this._startArrow.setControlPoint(controlPoints[1]);
|
|
||||||
|
|
||||||
event.stopPropagation();
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
_cleanOnMouseClick: function (event) {
|
|
||||||
|
|
||||||
// The user clicks on a desktop on in other element that is not a node.
|
|
||||||
this.dispose();
|
|
||||||
event.stopPropagation();
|
|
||||||
},
|
|
||||||
|
|
||||||
_calculateFromPosition: function (toPosition) {
|
|
||||||
|
|
||||||
// Calculate origin position ...
|
|
||||||
var sourcePosition = this._sourceTopic.getPosition();
|
|
||||||
if (this._sourceTopic.getType() == INodeModel.CENTRAL_TOPIC_TYPE) {
|
|
||||||
sourcePosition = Shape.workoutIncomingConnectionPoint(this._sourceTopic, toPosition);
|
|
||||||
}
|
|
||||||
var controlPoint = Shape.calculateDefaultControlPoints(sourcePosition, toPosition);
|
|
||||||
|
|
||||||
var spoint = new core.Point();
|
|
||||||
spoint.x = parseInt(controlPoint[0].x) + parseInt(sourcePosition.x);
|
|
||||||
spoint.y = parseInt(controlPoint[0].y) + parseInt(sourcePosition.y);
|
|
||||||
return Shape.calculateRelationShipPointCoordinates(this._sourceTopic, spoint);
|
|
||||||
},
|
|
||||||
|
|
||||||
_connectOnFocus: function (event, targetTopic) {
|
|
||||||
var sourceTopic = this._sourceTopic;
|
|
||||||
var mindmap = this._designer.getMindmap();
|
|
||||||
|
|
||||||
// Avoid circular connections ...
|
|
||||||
if (targetTopic.getId() != sourceTopic.getId()) {
|
|
||||||
var relModel = mindmap.createRelationship(targetTopic.getId(), sourceTopic.getId());
|
|
||||||
this._designer._actionDispatcher.addRelationship(relModel);
|
|
||||||
}
|
|
||||||
this.dispose();
|
|
||||||
},
|
|
||||||
|
|
||||||
_isActive: function () {
|
|
||||||
return this._pivot != null;
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
dispose() {
|
||||||
|
const workspace = this._workspace;
|
||||||
|
|
||||||
|
if (this._isActive()) {
|
||||||
|
workspace.removeEvent('mousemove', this._mouseMoveEvent);
|
||||||
|
workspace.removeEvent('click', this._onClickEvent);
|
||||||
|
|
||||||
|
const model = this._designer.getModel();
|
||||||
|
const topics = model.getTopics();
|
||||||
|
const me = this;
|
||||||
|
_.each(topics, (topic) => {
|
||||||
|
topic.removeEvent('ontfocus', me._onTopicClick);
|
||||||
|
});
|
||||||
|
|
||||||
|
workspace.removeChild(this._pivot);
|
||||||
|
workspace.removeChild(this._startArrow);
|
||||||
|
workspace.enableWorkspaceEvents(true);
|
||||||
|
|
||||||
|
this._sourceTopic = null;
|
||||||
|
this._pivot = null;
|
||||||
|
this._startArrow = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_mouseMove(event) {
|
||||||
|
const screen = this._workspace.getScreenManager();
|
||||||
|
const pos = screen.getWorkspaceMousePosition(event);
|
||||||
|
|
||||||
|
// Leave the arrow a couple of pixels away from the cursor.
|
||||||
|
const sourcePosition = this._sourceTopic.getPosition();
|
||||||
|
const gapDistance = Math.sign(pos.x - sourcePosition.x) * 5;
|
||||||
|
|
||||||
|
const sPos = this._calculateFromPosition(pos);
|
||||||
|
this._pivot.setFrom(sPos.x, sPos.y);
|
||||||
|
|
||||||
|
// Update target position ...
|
||||||
|
this._pivot.setTo(pos.x - gapDistance, pos.y);
|
||||||
|
|
||||||
|
const controlPoints = this._pivot.getControlPoints();
|
||||||
|
this._startArrow.setFrom(pos.x - gapDistance, pos.y);
|
||||||
|
this._startArrow.setControlPoint(controlPoints[1]);
|
||||||
|
|
||||||
|
event.stopPropagation();
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_cleanOnMouseClick(event) {
|
||||||
|
// The user clicks on a desktop on in other element that is not a node.
|
||||||
|
this.dispose();
|
||||||
|
event.stopPropagation();
|
||||||
|
},
|
||||||
|
|
||||||
|
_calculateFromPosition(toPosition) {
|
||||||
|
// Calculate origin position ...
|
||||||
|
let sourcePosition = this._sourceTopic.getPosition();
|
||||||
|
if (this._sourceTopic.getType() == INodeModel.CENTRAL_TOPIC_TYPE) {
|
||||||
|
sourcePosition = Shape.workoutIncomingConnectionPoint(this._sourceTopic, toPosition);
|
||||||
|
}
|
||||||
|
const controlPoint = Shape.calculateDefaultControlPoints(sourcePosition, toPosition);
|
||||||
|
|
||||||
|
const spoint = new core.Point();
|
||||||
|
spoint.x = parseInt(controlPoint[0].x) + parseInt(sourcePosition.x);
|
||||||
|
spoint.y = parseInt(controlPoint[0].y) + parseInt(sourcePosition.y);
|
||||||
|
return Shape.calculateRelationShipPointCoordinates(this._sourceTopic, spoint);
|
||||||
|
},
|
||||||
|
|
||||||
|
_connectOnFocus(event, targetTopic) {
|
||||||
|
const sourceTopic = this._sourceTopic;
|
||||||
|
const mindmap = this._designer.getMindmap();
|
||||||
|
|
||||||
|
// Avoid circular connections ...
|
||||||
|
if (targetTopic.getId() != sourceTopic.getId()) {
|
||||||
|
const relModel = mindmap.createRelationship(targetTopic.getId(), sourceTopic.getId());
|
||||||
|
this._designer._actionDispatcher.addRelationship(relModel);
|
||||||
|
}
|
||||||
|
this.dispose();
|
||||||
|
},
|
||||||
|
|
||||||
|
_isActive() {
|
||||||
|
return this._pivot != null;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default RelationshipPivot;
|
export default RelationshipPivot;
|
||||||
|
@ -18,149 +18,142 @@
|
|||||||
const PersistenceManager = require('./PersistenceManager').default;
|
const PersistenceManager = require('./PersistenceManager').default;
|
||||||
|
|
||||||
const RESTPersistenceManager = new Class({
|
const RESTPersistenceManager = new Class({
|
||||||
Extends: PersistenceManager,
|
Extends: PersistenceManager,
|
||||||
initialize: function (options) {
|
initialize(options) {
|
||||||
this.parent();
|
this.parent();
|
||||||
$assert(options.documentUrl, "documentUrl can not be null");
|
$assert(options.documentUrl, 'documentUrl can not be null');
|
||||||
$assert(options.revertUrl, "revertUrl can not be null");
|
$assert(options.revertUrl, 'revertUrl can not be null');
|
||||||
$assert(options.lockUrl, "lockUrl can not be null");
|
$assert(options.lockUrl, 'lockUrl can not be null');
|
||||||
$assert(options.session, "session can not be null");
|
$assert(options.session, 'session can not be null');
|
||||||
$assert(options.timestamp, "timestamp can not be null");
|
$assert(options.timestamp, 'timestamp can not be null');
|
||||||
|
|
||||||
this.documentUrl = options.documentUrl;
|
this.documentUrl = options.documentUrl;
|
||||||
this.revertUrl = options.revertUrl;
|
this.revertUrl = options.revertUrl;
|
||||||
this.lockUrl = options.lockUrl;
|
this.lockUrl = options.lockUrl;
|
||||||
this.timestamp = options.timestamp;
|
this.timestamp = options.timestamp;
|
||||||
this.session = options.session;
|
this.session = options.session;
|
||||||
|
},
|
||||||
|
|
||||||
|
saveMapXml(mapId, mapXml, pref, saveHistory, events, sync) {
|
||||||
|
const data = {
|
||||||
|
id: mapId,
|
||||||
|
xml: mapXml,
|
||||||
|
properties: pref,
|
||||||
|
};
|
||||||
|
|
||||||
|
const persistence = this;
|
||||||
|
let query = `minor=${!saveHistory}`;
|
||||||
|
query = `${query}×tamp=${this.timestamp}`;
|
||||||
|
query = `${query}&session=${this.session}`;
|
||||||
|
|
||||||
|
if (!persistence.onSave) {
|
||||||
|
// Mark save in process and fire a event unlocking the save ...
|
||||||
|
persistence.onSave = true;
|
||||||
|
persistence.clearTimeout = setTimeout(() => {
|
||||||
|
persistence.clearTimeout = null;
|
||||||
|
persistence.onSave = false;
|
||||||
|
}, 10000);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: `${this.documentUrl.replace('{id}', mapId)}?${query}`,
|
||||||
|
type: 'put',
|
||||||
|
dataType: 'json',
|
||||||
|
data: JSON.stringify(data),
|
||||||
|
contentType: 'application/json; charset=utf-8',
|
||||||
|
async: !sync,
|
||||||
|
|
||||||
|
success(data, textStatus, jqXHRresponseText) {
|
||||||
|
persistence.timestamp = data;
|
||||||
|
events.onSuccess();
|
||||||
},
|
},
|
||||||
|
error(jqXHR, textStatus, errorThrown) {
|
||||||
|
events.onError(persistence._buildError());
|
||||||
|
},
|
||||||
|
complete() {
|
||||||
|
// Clear event timeout ...
|
||||||
|
if (persistence.clearTimeout) {
|
||||||
|
clearTimeout(persistence.clearTimeout);
|
||||||
|
}
|
||||||
|
persistence.onSave = false;
|
||||||
|
},
|
||||||
|
fail(xhr, textStatus) {
|
||||||
|
const { responseText } = xhr;
|
||||||
|
let userMsg = { severity: 'SEVERE', message: $msg('SAVE_COULD_NOT_BE_COMPLETED') };
|
||||||
|
|
||||||
saveMapXml: function (mapId, mapXml, pref, saveHistory, events, sync) {
|
const contentType = xhr.getResponseHeader('Content-Type');
|
||||||
|
if (contentType != null && contentType.indexOf('application/json') != -1) {
|
||||||
var data = {
|
let serverMsg = null;
|
||||||
id: mapId,
|
try {
|
||||||
xml: mapXml,
|
serverMsg = $.parseJSON(responseText);
|
||||||
properties: pref
|
serverMsg = serverMsg.globalSeverity ? serverMsg : null;
|
||||||
};
|
} catch (e) {
|
||||||
|
// Message could not be decoded ...
|
||||||
var persistence = this;
|
|
||||||
var query = "minor=" + !saveHistory;
|
|
||||||
query = query + "×tamp=" + this.timestamp;
|
|
||||||
query = query + "&session=" + this.session;
|
|
||||||
|
|
||||||
if (!persistence.onSave) {
|
|
||||||
|
|
||||||
// Mark save in process and fire a event unlocking the save ...
|
|
||||||
persistence.onSave = true;
|
|
||||||
persistence.clearTimeout = setTimeout(function () {
|
|
||||||
persistence.clearTimeout = null;
|
|
||||||
persistence.onSave = false;
|
|
||||||
}, 10000);
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url: this.documentUrl.replace("{id}", mapId) + "?" + query,
|
|
||||||
type: 'put',
|
|
||||||
dataType: "json",
|
|
||||||
data: JSON.stringify(data),
|
|
||||||
contentType: "application/json; charset=utf-8",
|
|
||||||
async: !sync,
|
|
||||||
|
|
||||||
success: function (data, textStatus, jqXHRresponseText) {
|
|
||||||
persistence.timestamp = data;
|
|
||||||
events.onSuccess();
|
|
||||||
},
|
|
||||||
error: function (jqXHR, textStatus, errorThrown) {
|
|
||||||
events.onError(persistence._buildError());
|
|
||||||
},
|
|
||||||
complete: function () {
|
|
||||||
// Clear event timeout ...
|
|
||||||
if (persistence.clearTimeout) {
|
|
||||||
clearTimeout(persistence.clearTimeout);
|
|
||||||
}
|
|
||||||
persistence.onSave = false;
|
|
||||||
},
|
|
||||||
fail: function (xhr, textStatus) {
|
|
||||||
|
|
||||||
var responseText = xhr.responseText;
|
|
||||||
var userMsg = {severity: "SEVERE", message: $msg('SAVE_COULD_NOT_BE_COMPLETED')};
|
|
||||||
|
|
||||||
var contentType = xhr.getResponseHeader("Content-Type");
|
|
||||||
if (contentType != null && contentType.indexOf("application/json") != -1) {
|
|
||||||
var serverMsg = null;
|
|
||||||
try {
|
|
||||||
serverMsg = $.parseJSON(responseText);
|
|
||||||
serverMsg = serverMsg.globalSeverity ? serverMsg : null;
|
|
||||||
} catch (e) {
|
|
||||||
// Message could not be decoded ...
|
|
||||||
}
|
|
||||||
userMsg = persistence._buildError(serverMsg);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
if (this.status == 405) {
|
|
||||||
userMsg = {severity: "SEVERE", message: $msg('SESSION_EXPIRED')};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
events.onError(userMsg);
|
|
||||||
persistence.onSave = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
userMsg = persistence._buildError(serverMsg);
|
||||||
|
} else if (this.status == 405) {
|
||||||
|
userMsg = { severity: 'SEVERE', message: $msg('SESSION_EXPIRED') };
|
||||||
|
}
|
||||||
|
events.onError(userMsg);
|
||||||
|
persistence.onSave = false;
|
||||||
},
|
},
|
||||||
|
});
|
||||||
discardChanges: function (mapId) {
|
|
||||||
$.ajax({
|
|
||||||
url: this.revertUrl.replace("{id}", mapId),
|
|
||||||
async: false,
|
|
||||||
method: 'post',
|
|
||||||
headers: {"Content-Type": "application/json; charset=utf-8", "Accept": "application/json"}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
unlockMap: function (mindmap) {
|
|
||||||
var mapId = mindmap.getId();
|
|
||||||
$.ajax({
|
|
||||||
url: this.lockUrl.replace("{id}", mapId),
|
|
||||||
async: false,
|
|
||||||
method: 'put',
|
|
||||||
headers: {"Content-Type": "text/plain"},
|
|
||||||
data: "false"
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
_buildError: function (jsonSeverResponse) {
|
|
||||||
var message = jsonSeverResponse ? jsonSeverResponse.globalErrors[0] : null;
|
|
||||||
var severity = jsonSeverResponse ? jsonSeverResponse.globalSeverity : null;
|
|
||||||
|
|
||||||
if (!message) {
|
|
||||||
message = $msg('SAVE_COULD_NOT_BE_COMPLETED');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!severity) {
|
|
||||||
severity = "INFO";
|
|
||||||
}
|
|
||||||
return {severity: severity, message: message};
|
|
||||||
},
|
|
||||||
|
|
||||||
loadMapDom: function (mapId) {
|
|
||||||
// Let's try to open one from the local directory ...
|
|
||||||
var xml;
|
|
||||||
$.ajax({
|
|
||||||
url: this.documentUrl.replace("{id}", mapId) + "/xml",
|
|
||||||
method: 'get',
|
|
||||||
async: false,
|
|
||||||
headers: {"Content-Type": "text/plain", "Accept": "application/xml"},
|
|
||||||
success: function (responseText) {
|
|
||||||
xml = responseText;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// If I could not load it from a file, hard code one.
|
|
||||||
if (xml == null) {
|
|
||||||
throw new Error("Map could not be loaded");
|
|
||||||
}
|
|
||||||
|
|
||||||
return xml;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
},
|
||||||
|
|
||||||
|
discardChanges(mapId) {
|
||||||
|
$.ajax({
|
||||||
|
url: this.revertUrl.replace('{id}', mapId),
|
||||||
|
async: false,
|
||||||
|
method: 'post',
|
||||||
|
headers: { 'Content-Type': 'application/json; charset=utf-8', Accept: 'application/json' },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
unlockMap(mindmap) {
|
||||||
|
const mapId = mindmap.getId();
|
||||||
|
$.ajax({
|
||||||
|
url: this.lockUrl.replace('{id}', mapId),
|
||||||
|
async: false,
|
||||||
|
method: 'put',
|
||||||
|
headers: { 'Content-Type': 'text/plain' },
|
||||||
|
data: 'false',
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_buildError(jsonSeverResponse) {
|
||||||
|
let message = jsonSeverResponse ? jsonSeverResponse.globalErrors[0] : null;
|
||||||
|
let severity = jsonSeverResponse ? jsonSeverResponse.globalSeverity : null;
|
||||||
|
|
||||||
|
if (!message) {
|
||||||
|
message = $msg('SAVE_COULD_NOT_BE_COMPLETED');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!severity) {
|
||||||
|
severity = 'INFO';
|
||||||
|
}
|
||||||
|
return { severity, message };
|
||||||
|
},
|
||||||
|
|
||||||
|
loadMapDom(mapId) {
|
||||||
|
// Let's try to open one from the local directory ...
|
||||||
|
let xml;
|
||||||
|
$.ajax({
|
||||||
|
url: `${this.documentUrl.replace('{id}', mapId)}/xml`,
|
||||||
|
method: 'get',
|
||||||
|
async: false,
|
||||||
|
headers: { 'Content-Type': 'text/plain', Accept: 'application/xml' },
|
||||||
|
success(responseText) {
|
||||||
|
xml = responseText;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// If I could not load it from a file, hard code one.
|
||||||
|
if (xml == null) {
|
||||||
|
throw new Error('Map could not be loaded');
|
||||||
|
}
|
||||||
|
|
||||||
|
return xml;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export default RESTPersistenceManager;
|
export default RESTPersistenceManager;
|
||||||
|
@ -16,138 +16,135 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
const Core = require('@wismapping/core-js');
|
const Core = require('@wismapping/core-js');
|
||||||
|
|
||||||
const core = Core();
|
const core = Core();
|
||||||
|
|
||||||
const ScreenManager = new Class({
|
const ScreenManager = new Class({
|
||||||
initialize: function (divElement) {
|
initialize(divElement) {
|
||||||
$assert(divElement, "can not be null");
|
$assert(divElement, 'can not be null');
|
||||||
this._divContainer = divElement;
|
this._divContainer = divElement;
|
||||||
this._padding = {x: 0, y: 0};
|
this._padding = { x: 0, y: 0 };
|
||||||
|
|
||||||
// Ignore default click event propagation. Prevent 'click' event on drag.
|
// Ignore default click event propagation. Prevent 'click' event on drag.
|
||||||
this._clickEvents = [];
|
this._clickEvents = [];
|
||||||
this._divContainer.bind('click', function (event) {
|
this._divContainer.bind('click', (event) => {
|
||||||
event.stopPropagation()
|
event.stopPropagation();
|
||||||
});
|
});
|
||||||
|
|
||||||
this._divContainer.bind('dblclick', function (event) {
|
this._divContainer.bind('dblclick', (event) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
setScale: function (scale) {
|
setScale(scale) {
|
||||||
$assert(scale, 'Screen scale can not be null');
|
$assert(scale, 'Screen scale can not be null');
|
||||||
this._scale = scale;
|
this._scale = scale;
|
||||||
},
|
},
|
||||||
|
|
||||||
addEvent: function (event, listener) {
|
addEvent(event, listener) {
|
||||||
if (event == 'click')
|
if (event == 'click') this._clickEvents.push(listener);
|
||||||
this._clickEvents.push(listener);
|
else this._divContainer.bind(event, listener);
|
||||||
else
|
},
|
||||||
this._divContainer.bind(event, listener);
|
|
||||||
},
|
|
||||||
|
|
||||||
removeEvent: function (event, listener) {
|
removeEvent(event, listener) {
|
||||||
if (event == 'click') {
|
if (event == 'click') {
|
||||||
this._clickEvents.remove(listener);
|
this._clickEvents.remove(listener);
|
||||||
}
|
} else {
|
||||||
else {
|
this._divContainer.unbind(event, listener);
|
||||||
this._divContainer.unbind(event, listener);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
fireEvent: function (type, event) {
|
|
||||||
if (type == 'click') {
|
|
||||||
_.each(this._clickEvents, function (listener) {
|
|
||||||
listener(type, event);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this._divContainer.trigger(type, event);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_getElementPosition: function (elem) {
|
|
||||||
// Retrieve current element position.
|
|
||||||
var elementPosition = elem.getPosition();
|
|
||||||
var x = elementPosition.x;
|
|
||||||
var y = elementPosition.y;
|
|
||||||
|
|
||||||
// Add workspace offset.
|
|
||||||
x = x - this._padding.x;
|
|
||||||
y = y - this._padding.y;
|
|
||||||
|
|
||||||
// Scale coordinate in order to be relative to the workspace. That's coord/size;
|
|
||||||
x = x / this._scale;
|
|
||||||
y = y / this._scale;
|
|
||||||
|
|
||||||
// Remove decimal part..
|
|
||||||
return {x: x, y: y};
|
|
||||||
},
|
|
||||||
|
|
||||||
getWorkspaceIconPosition: function (e) {
|
|
||||||
// Retrieve current icon position.
|
|
||||||
var image = e.getImage();
|
|
||||||
var elementPosition = image.getPosition();
|
|
||||||
var imageSize = e.getSize();
|
|
||||||
|
|
||||||
//Add group offset
|
|
||||||
var iconGroup = e.getGroup();
|
|
||||||
var group = iconGroup.getNativeElement();
|
|
||||||
var coordOrigin = group.getCoordOrigin();
|
|
||||||
var groupSize = group.getSize();
|
|
||||||
var coordSize = group.getCoordSize();
|
|
||||||
|
|
||||||
var scale = {x: coordSize.width / parseInt(groupSize.width), y: coordSize.height / parseInt(groupSize.height)};
|
|
||||||
|
|
||||||
var x = (elementPosition.x - coordOrigin.x - (parseInt(imageSize.width) / 2)) / scale.x;
|
|
||||||
var y = (elementPosition.y - coordOrigin.y - (parseInt(imageSize.height) / 2)) / scale.y;
|
|
||||||
|
|
||||||
//Retrieve iconGroup Position
|
|
||||||
var groupPosition = iconGroup.getPosition();
|
|
||||||
x = x + groupPosition.x;
|
|
||||||
y = y + groupPosition.y;
|
|
||||||
|
|
||||||
//Retrieve topic Position
|
|
||||||
var topic = iconGroup.getTopic();
|
|
||||||
var topicPosition = this._getElementPosition(topic);
|
|
||||||
topicPosition.x = topicPosition.x - (parseInt(topic.getSize().width) / 2);
|
|
||||||
|
|
||||||
// Remove decimal part..
|
|
||||||
return {x: x + topicPosition.x, y: y + topicPosition.y};
|
|
||||||
},
|
|
||||||
|
|
||||||
getWorkspaceMousePosition: function (event) {
|
|
||||||
// Retrieve current mouse position.
|
|
||||||
var x = event.clientX;
|
|
||||||
var y = event.clientY;
|
|
||||||
|
|
||||||
//FIXME: paulo: why? Subtract div position.
|
|
||||||
/*var containerPosition = this.getContainer().position();
|
|
||||||
x = x - containerPosition.x;
|
|
||||||
y = y - containerPosition.y;*/
|
|
||||||
|
|
||||||
// Scale coordinate in order to be relative to the workspace. That's coordSize/size;
|
|
||||||
x = x * this._scale;
|
|
||||||
y = y * this._scale;
|
|
||||||
|
|
||||||
// Add workspace offset.
|
|
||||||
x = x + this._padding.x;
|
|
||||||
y = y + this._padding.y;
|
|
||||||
|
|
||||||
// Remove decimal part..
|
|
||||||
return new core.Point(x, y);
|
|
||||||
},
|
|
||||||
|
|
||||||
getContainer: function () {
|
|
||||||
return this._divContainer;
|
|
||||||
},
|
|
||||||
|
|
||||||
setOffset: function (x, y) {
|
|
||||||
this._padding.x = x;
|
|
||||||
this._padding.y = y;
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
fireEvent(type, event) {
|
||||||
|
if (type == 'click') {
|
||||||
|
_.each(this._clickEvents, (listener) => {
|
||||||
|
listener(type, event);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this._divContainer.trigger(type, event);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_getElementPosition(elem) {
|
||||||
|
// Retrieve current element position.
|
||||||
|
const elementPosition = elem.getPosition();
|
||||||
|
let { x } = elementPosition;
|
||||||
|
let { y } = elementPosition;
|
||||||
|
|
||||||
|
// Add workspace offset.
|
||||||
|
x -= this._padding.x;
|
||||||
|
y -= this._padding.y;
|
||||||
|
|
||||||
|
// Scale coordinate in order to be relative to the workspace. That's coord/size;
|
||||||
|
x /= this._scale;
|
||||||
|
y /= this._scale;
|
||||||
|
|
||||||
|
// Remove decimal part..
|
||||||
|
return { x, y };
|
||||||
|
},
|
||||||
|
|
||||||
|
getWorkspaceIconPosition(e) {
|
||||||
|
// Retrieve current icon position.
|
||||||
|
const image = e.getImage();
|
||||||
|
const elementPosition = image.getPosition();
|
||||||
|
const imageSize = e.getSize();
|
||||||
|
|
||||||
|
// Add group offset
|
||||||
|
const iconGroup = e.getGroup();
|
||||||
|
const group = iconGroup.getNativeElement();
|
||||||
|
const coordOrigin = group.getCoordOrigin();
|
||||||
|
const groupSize = group.getSize();
|
||||||
|
const coordSize = group.getCoordSize();
|
||||||
|
|
||||||
|
const scale = { x: coordSize.width / parseInt(groupSize.width), y: coordSize.height / parseInt(groupSize.height) };
|
||||||
|
|
||||||
|
let x = (elementPosition.x - coordOrigin.x - (parseInt(imageSize.width) / 2)) / scale.x;
|
||||||
|
let y = (elementPosition.y - coordOrigin.y - (parseInt(imageSize.height) / 2)) / scale.y;
|
||||||
|
|
||||||
|
// Retrieve iconGroup Position
|
||||||
|
const groupPosition = iconGroup.getPosition();
|
||||||
|
x += groupPosition.x;
|
||||||
|
y += groupPosition.y;
|
||||||
|
|
||||||
|
// Retrieve topic Position
|
||||||
|
const topic = iconGroup.getTopic();
|
||||||
|
const topicPosition = this._getElementPosition(topic);
|
||||||
|
topicPosition.x -= (parseInt(topic.getSize().width) / 2);
|
||||||
|
|
||||||
|
// Remove decimal part..
|
||||||
|
return { x: x + topicPosition.x, y: y + topicPosition.y };
|
||||||
|
},
|
||||||
|
|
||||||
|
getWorkspaceMousePosition(event) {
|
||||||
|
// Retrieve current mouse position.
|
||||||
|
let x = event.clientX;
|
||||||
|
let y = event.clientY;
|
||||||
|
|
||||||
|
// FIXME: paulo: why? Subtract div position.
|
||||||
|
/* var containerPosition = this.getContainer().position();
|
||||||
|
x = x - containerPosition.x;
|
||||||
|
y = y - containerPosition.y; */
|
||||||
|
|
||||||
|
// Scale coordinate in order to be relative to the workspace. That's coordSize/size;
|
||||||
|
x *= this._scale;
|
||||||
|
y *= this._scale;
|
||||||
|
|
||||||
|
// Add workspace offset.
|
||||||
|
x += this._padding.x;
|
||||||
|
y += this._padding.y;
|
||||||
|
|
||||||
|
// Remove decimal part..
|
||||||
|
return new core.Point(x, y);
|
||||||
|
},
|
||||||
|
|
||||||
|
getContainer() {
|
||||||
|
return this._divContainer;
|
||||||
|
},
|
||||||
|
|
||||||
|
setOffset(x, y) {
|
||||||
|
this._padding.x = x;
|
||||||
|
this._padding.y = y;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default ScreenManager;
|
export default ScreenManager;
|
||||||
|
@ -15,100 +15,97 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
const web2D = require('@wismapping/web2d')
|
const web2D = require('@wismapping/web2d');
|
||||||
|
|
||||||
const web2d = web2D();
|
const web2d = web2D();
|
||||||
|
|
||||||
const Topic = require('./Topic').default
|
const Topic = require('./Topic').default;
|
||||||
const ActionDispatcher = require('./ActionDispatcher').default;
|
const ActionDispatcher = require('./ActionDispatcher').default;
|
||||||
|
|
||||||
const ShirinkConnector = new Class({
|
const ShirinkConnector = new Class({
|
||||||
initialize: function (topic) {
|
initialize(topic) {
|
||||||
|
const ellipse = new web2D.Elipse(Topic.prototype.INNER_RECT_ATTRIBUTES);
|
||||||
|
this._ellipse = ellipse;
|
||||||
|
ellipse.setFill('rgb(62,118,179)');
|
||||||
|
|
||||||
var ellipse = new web2D.Elipse(Topic.prototype.INNER_RECT_ATTRIBUTES);
|
ellipse.setSize(Topic.CONNECTOR_WIDTH, Topic.CONNECTOR_WIDTH);
|
||||||
this._ellipse = ellipse;
|
ellipse.addEvent('click', (event) => {
|
||||||
ellipse.setFill('rgb(62,118,179)');
|
const model = topic.getModel();
|
||||||
|
const collapse = !model.areChildrenShrunken();
|
||||||
|
|
||||||
ellipse.setSize(Topic.CONNECTOR_WIDTH, Topic.CONNECTOR_WIDTH);
|
const topicId = topic.getId();
|
||||||
ellipse.addEvent('click', function (event) {
|
const actionDispatcher = ActionDispatcher.getInstance();
|
||||||
var model = topic.getModel();
|
actionDispatcher.shrinkBranch([topicId], collapse);
|
||||||
var collapse = !model.areChildrenShrunken();
|
|
||||||
|
|
||||||
var topicId = topic.getId();
|
event.stopPropagation();
|
||||||
var actionDispatcher = ActionDispatcher.getInstance();
|
});
|
||||||
actionDispatcher.shrinkBranch([topicId], collapse);
|
|
||||||
|
|
||||||
event.stopPropagation();
|
ellipse.addEvent('mousedown', (event) => {
|
||||||
|
// Avoid node creation ...
|
||||||
|
event.stopPropagation();
|
||||||
|
});
|
||||||
|
|
||||||
});
|
ellipse.addEvent('dblclick', (event) => {
|
||||||
|
// Avoid node creation ...
|
||||||
|
event.stopPropagation();
|
||||||
|
});
|
||||||
|
|
||||||
ellipse.addEvent('mousedown', function (event) {
|
ellipse.addEvent('mouseover', (event) => {
|
||||||
// Avoid node creation ...
|
ellipse.setFill('rgb(153, 0, 255)');
|
||||||
event.stopPropagation();
|
});
|
||||||
});
|
const me = this;
|
||||||
|
ellipse.addEvent('mouseout', (event) => {
|
||||||
|
const color = topic.getBackgroundColor();
|
||||||
|
me.setFill(color);
|
||||||
|
});
|
||||||
|
|
||||||
ellipse.addEvent('dblclick', function (event) {
|
ellipse.setCursor('default');
|
||||||
// Avoid node creation ...
|
this._fillColor = '#f7f7f7';
|
||||||
event.stopPropagation();
|
const model = topic.getModel();
|
||||||
});
|
this.changeRender(model.areChildrenShrunken());
|
||||||
|
},
|
||||||
|
|
||||||
ellipse.addEvent('mouseover', function (event) {
|
changeRender(isShrink) {
|
||||||
|
const elipse = this._ellipse;
|
||||||
ellipse.setFill('rgb(153, 0, 255)');
|
if (isShrink) {
|
||||||
});
|
elipse.setStroke('2', 'solid');
|
||||||
var me = this;
|
} else {
|
||||||
ellipse.addEvent('mouseout', function (event) {
|
elipse.setStroke('1', 'solid');
|
||||||
var color = topic.getBackgroundColor();
|
|
||||||
me.setFill(color);
|
|
||||||
});
|
|
||||||
|
|
||||||
ellipse.setCursor('default');
|
|
||||||
this._fillColor = '#f7f7f7';
|
|
||||||
var model = topic.getModel();
|
|
||||||
this.changeRender(model.areChildrenShrunken());
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
changeRender: function (isShrink) {
|
|
||||||
var elipse = this._ellipse;
|
|
||||||
if (isShrink) {
|
|
||||||
elipse.setStroke('2', 'solid');
|
|
||||||
} else {
|
|
||||||
elipse.setStroke('1', 'solid');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
setVisibility: function (value) {
|
|
||||||
this._ellipse.setVisibility(value);
|
|
||||||
},
|
|
||||||
|
|
||||||
setOpacity: function (opacity) {
|
|
||||||
this._ellipse.setOpacity(opacity);
|
|
||||||
},
|
|
||||||
|
|
||||||
setFill: function (color) {
|
|
||||||
this._fillColor = color;
|
|
||||||
this._ellipse.setFill(color);
|
|
||||||
},
|
|
||||||
|
|
||||||
setAttribute: function (name, value) {
|
|
||||||
this._ellipse.setAttribute(name, value);
|
|
||||||
},
|
|
||||||
|
|
||||||
addToWorkspace: function (group) {
|
|
||||||
group.append(this._ellipse);
|
|
||||||
},
|
|
||||||
|
|
||||||
setPosition: function (x, y) {
|
|
||||||
this._ellipse.setPosition(x, y);
|
|
||||||
},
|
|
||||||
|
|
||||||
moveToBack: function () {
|
|
||||||
this._ellipse.moveToBack();
|
|
||||||
},
|
|
||||||
|
|
||||||
moveToFront: function () {
|
|
||||||
this._ellipse.moveToFront();
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setVisibility(value) {
|
||||||
|
this._ellipse.setVisibility(value);
|
||||||
|
},
|
||||||
|
|
||||||
|
setOpacity(opacity) {
|
||||||
|
this._ellipse.setOpacity(opacity);
|
||||||
|
},
|
||||||
|
|
||||||
|
setFill(color) {
|
||||||
|
this._fillColor = color;
|
||||||
|
this._ellipse.setFill(color);
|
||||||
|
},
|
||||||
|
|
||||||
|
setAttribute(name, value) {
|
||||||
|
this._ellipse.setAttribute(name, value);
|
||||||
|
},
|
||||||
|
|
||||||
|
addToWorkspace(group) {
|
||||||
|
group.append(this._ellipse);
|
||||||
|
},
|
||||||
|
|
||||||
|
setPosition(x, y) {
|
||||||
|
this._ellipse.setPosition(x, y);
|
||||||
|
},
|
||||||
|
|
||||||
|
moveToBack() {
|
||||||
|
this._ellipse.moveToBack();
|
||||||
|
},
|
||||||
|
|
||||||
|
moveToFront() {
|
||||||
|
this._ellipse.moveToFront();
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default ShirinkConnector;
|
export default ShirinkConnector;
|
||||||
|
@ -29,353 +29,347 @@ const ChangeFeatureToTopicCommand = require('./commands/ChangeFeatureToTopicComm
|
|||||||
const NodeModel = require('./model/NodeModel').default;
|
const NodeModel = require('./model/NodeModel').default;
|
||||||
|
|
||||||
const StandaloneActionDispatcher = new Class(
|
const StandaloneActionDispatcher = new Class(
|
||||||
/** @lends StandaloneActionDispatcher */ {
|
/** @lends StandaloneActionDispatcher */ {
|
||||||
Extends: ActionDispatcher,
|
Extends: ActionDispatcher,
|
||||||
/**
|
/**
|
||||||
* @extends mindplot.ActionDispatcher
|
* @extends mindplot.ActionDispatcher
|
||||||
* @constructs
|
* @constructs
|
||||||
* @param {mindplot.CommandContext} commandContext
|
* @param {mindplot.CommandContext} commandContext
|
||||||
*/
|
*/
|
||||||
initialize: function (commandContext) {
|
initialize(commandContext) {
|
||||||
this.parent(commandContext);
|
this.parent(commandContext);
|
||||||
this._actionRunner = new DesignerActionRunner(commandContext, this);
|
this._actionRunner = new DesignerActionRunner(commandContext, this);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
addTopics: function (models, parentTopicsId) {
|
addTopics(models, parentTopicsId) {
|
||||||
var command = new AddTopicCommand(models, parentTopicsId);
|
const command = new AddTopicCommand(models, parentTopicsId);
|
||||||
this.execute(command);
|
this.execute(command);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
addRelationship: function (model) {
|
addRelationship(model) {
|
||||||
var command = new AddRelationshipCommand(model);
|
const command = new AddRelationshipCommand(model);
|
||||||
this.execute(command);
|
this.execute(command);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
deleteEntities: function (topicsIds, relIds) {
|
deleteEntities(topicsIds, relIds) {
|
||||||
var command = new DeleteCommand(topicsIds, relIds);
|
const command = new DeleteCommand(topicsIds, relIds);
|
||||||
this.execute(command);
|
this.execute(command);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
dragTopic: function (topicId, position, order, parentTopic) {
|
dragTopic(topicId, position, order, parentTopic) {
|
||||||
var command = new DragTopicCommand(topicId, position, order, parentTopic);
|
const command = new DragTopicCommand(topicId, position, order, parentTopic);
|
||||||
this.execute(command);
|
this.execute(command);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
moveTopic: function (topicId, position) {
|
moveTopic(topicId, position) {
|
||||||
$assert($defined(topicId), 'topicsId can not be null');
|
$assert($defined(topicId), 'topicsId can not be null');
|
||||||
$assert($defined(position), 'position can not be null');
|
$assert($defined(position), 'position can not be null');
|
||||||
|
|
||||||
var commandFunc = function (topic, value) {
|
const commandFunc = function (topic, value) {
|
||||||
var result = topic.getPosition();
|
const result = topic.getPosition();
|
||||||
EventBus.instance.fireEvent(EventBus.events.NodeMoveEvent, {
|
EventBus.instance.fireEvent(EventBus.events.NodeMoveEvent, {
|
||||||
node: topic.getModel(),
|
node: topic.getModel(),
|
||||||
position: value,
|
position: value,
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
var command = new GenericFunctionCommand(commandFunc, topicId, position);
|
const command = new GenericFunctionCommand(commandFunc, topicId, position);
|
||||||
this.execute(command);
|
this.execute(command);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
moveControlPoint: function (ctrlPoint, point) {
|
moveControlPoint(ctrlPoint, point) {
|
||||||
var command = new MoveControlPointCommand(ctrlPoint, point);
|
const command = new MoveControlPointCommand(ctrlPoint, point);
|
||||||
this.execute(command);
|
this.execute(command);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
changeFontStyleToTopic: function (topicsIds) {
|
changeFontStyleToTopic(topicsIds) {
|
||||||
var commandFunc = function (topic) {
|
const commandFunc = function (topic) {
|
||||||
var result = topic.getFontStyle();
|
const result = topic.getFontStyle();
|
||||||
var style = result == 'italic' ? 'normal' : 'italic';
|
const style = result == 'italic' ? 'normal' : 'italic';
|
||||||
topic.setFontStyle(style, true);
|
topic.setFontStyle(style, true);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
var command = new GenericFunctionCommand(commandFunc, topicsIds);
|
const command = new GenericFunctionCommand(commandFunc, topicsIds);
|
||||||
this.execute(command);
|
this.execute(command);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
changeTextToTopic: function (topicsIds, text) {
|
changeTextToTopic(topicsIds, text) {
|
||||||
$assert($defined(topicsIds), 'topicsIds can not be null');
|
$assert($defined(topicsIds), 'topicsIds can not be null');
|
||||||
|
|
||||||
var commandFunc = function (topic, value) {
|
const commandFunc = function (topic, value) {
|
||||||
var result = topic.getText();
|
const result = topic.getText();
|
||||||
topic.setText(value);
|
topic.setText(value);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
commandFunc.commandType = 'changeTextToTopic';
|
commandFunc.commandType = 'changeTextToTopic';
|
||||||
|
|
||||||
var command = new GenericFunctionCommand(commandFunc, topicsIds, text);
|
const command = new GenericFunctionCommand(commandFunc, topicsIds, text);
|
||||||
this.execute(command);
|
this.execute(command);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
changeFontFamilyToTopic: function (topicIds, fontFamily) {
|
changeFontFamilyToTopic(topicIds, fontFamily) {
|
||||||
$assert(topicIds, 'topicIds can not be null');
|
$assert(topicIds, 'topicIds can not be null');
|
||||||
$assert(fontFamily, 'fontFamily can not be null');
|
$assert(fontFamily, 'fontFamily can not be null');
|
||||||
|
|
||||||
var commandFunc = function (topic, fontFamily) {
|
const commandFunc = function (topic, fontFamily) {
|
||||||
var result = topic.getFontFamily();
|
const result = topic.getFontFamily();
|
||||||
topic.setFontFamily(fontFamily, true);
|
topic.setFontFamily(fontFamily, true);
|
||||||
|
|
||||||
topic._adjustShapes();
|
topic._adjustShapes();
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
var command = new GenericFunctionCommand(commandFunc, topicIds, fontFamily);
|
const command = new GenericFunctionCommand(commandFunc, topicIds, fontFamily);
|
||||||
this.execute(command);
|
this.execute(command);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
changeFontColorToTopic: function (topicsIds, color) {
|
changeFontColorToTopic(topicsIds, color) {
|
||||||
$assert(topicsIds, 'topicIds can not be null');
|
$assert(topicsIds, 'topicIds can not be null');
|
||||||
$assert(color, 'color can not be null');
|
$assert(color, 'color can not be null');
|
||||||
|
|
||||||
var commandFunc = function (topic, color) {
|
const commandFunc = function (topic, color) {
|
||||||
var result = topic.getFontColor();
|
const result = topic.getFontColor();
|
||||||
topic.setFontColor(color, true);
|
topic.setFontColor(color, true);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
var command = new GenericFunctionCommand(commandFunc, topicsIds, color);
|
const command = new GenericFunctionCommand(commandFunc, topicsIds, color);
|
||||||
command.discardDuplicated = 'fontColorCommandId';
|
command.discardDuplicated = 'fontColorCommandId';
|
||||||
this.execute(command);
|
this.execute(command);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
changeBackgroundColorToTopic: function (topicsIds, color) {
|
changeBackgroundColorToTopic(topicsIds, color) {
|
||||||
$assert(topicsIds, 'topicIds can not be null');
|
$assert(topicsIds, 'topicIds can not be null');
|
||||||
$assert(color, 'color can not be null');
|
$assert(color, 'color can not be null');
|
||||||
|
|
||||||
var commandFunc = function (topic, color) {
|
const commandFunc = function (topic, color) {
|
||||||
var result = topic.getBackgroundColor();
|
const result = topic.getBackgroundColor();
|
||||||
topic.setBackgroundColor(color);
|
topic.setBackgroundColor(color);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
var command = new GenericFunctionCommand(commandFunc, topicsIds, color);
|
const command = new GenericFunctionCommand(commandFunc, topicsIds, color);
|
||||||
command.discardDuplicated = 'backColor';
|
command.discardDuplicated = 'backColor';
|
||||||
this.execute(command);
|
this.execute(command);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
changeBorderColorToTopic: function (topicsIds, color) {
|
changeBorderColorToTopic(topicsIds, color) {
|
||||||
$assert(topicsIds, 'topicIds can not be null');
|
$assert(topicsIds, 'topicIds can not be null');
|
||||||
$assert(color, 'topicIds can not be null');
|
$assert(color, 'topicIds can not be null');
|
||||||
|
|
||||||
var commandFunc = function (topic, color) {
|
const commandFunc = function (topic, color) {
|
||||||
var result = topic.getBorderColor();
|
const result = topic.getBorderColor();
|
||||||
topic.setBorderColor(color);
|
topic.setBorderColor(color);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
var command = new GenericFunctionCommand(commandFunc, topicsIds, color);
|
const command = new GenericFunctionCommand(commandFunc, topicsIds, color);
|
||||||
command.discardDuplicated = 'borderColorCommandId';
|
command.discardDuplicated = 'borderColorCommandId';
|
||||||
this.execute(command);
|
this.execute(command);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
changeFontSizeToTopic: function (topicsIds, size) {
|
changeFontSizeToTopic(topicsIds, size) {
|
||||||
$assert(topicsIds, 'topicIds can not be null');
|
$assert(topicsIds, 'topicIds can not be null');
|
||||||
$assert(size, 'size can not be null');
|
$assert(size, 'size can not be null');
|
||||||
|
|
||||||
var commandFunc = function (topic, size) {
|
const commandFunc = function (topic, size) {
|
||||||
var result = topic.getFontSize();
|
const result = topic.getFontSize();
|
||||||
topic.setFontSize(size, true);
|
topic.setFontSize(size, true);
|
||||||
|
|
||||||
topic._adjustShapes();
|
topic._adjustShapes();
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
var command = new GenericFunctionCommand(commandFunc, topicsIds, size);
|
const command = new GenericFunctionCommand(commandFunc, topicsIds, size);
|
||||||
this.execute(command);
|
this.execute(command);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
changeShapeTypeToTopic: function (topicsIds, shapeType) {
|
changeShapeTypeToTopic(topicsIds, shapeType) {
|
||||||
$assert(topicsIds, 'topicsIds can not be null');
|
$assert(topicsIds, 'topicsIds can not be null');
|
||||||
$assert(shapeType, 'shapeType can not be null');
|
$assert(shapeType, 'shapeType can not be null');
|
||||||
|
|
||||||
var commandFunc = function (topic, shapeType) {
|
const commandFunc = function (topic, shapeType) {
|
||||||
var result = topic.getShapeType();
|
const result = topic.getShapeType();
|
||||||
topic.setShapeType(shapeType, true);
|
topic.setShapeType(shapeType, true);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
var command = new GenericFunctionCommand(commandFunc, topicsIds, shapeType);
|
const command = new GenericFunctionCommand(commandFunc, topicsIds, shapeType);
|
||||||
this.execute(command);
|
this.execute(command);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
changeFontWeightToTopic: function (topicsIds) {
|
changeFontWeightToTopic(topicsIds) {
|
||||||
$assert(topicsIds, 'topicsIds can not be null');
|
$assert(topicsIds, 'topicsIds can not be null');
|
||||||
|
|
||||||
var commandFunc = function (topic) {
|
const commandFunc = function (topic) {
|
||||||
var result = topic.getFontWeight();
|
const result = topic.getFontWeight();
|
||||||
var weight = result == 'bold' ? 'normal' : 'bold';
|
const weight = result == 'bold' ? 'normal' : 'bold';
|
||||||
topic.setFontWeight(weight, true);
|
topic.setFontWeight(weight, true);
|
||||||
|
|
||||||
topic._adjustShapes();
|
topic._adjustShapes();
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
var command = new GenericFunctionCommand(commandFunc, topicsIds);
|
const command = new GenericFunctionCommand(commandFunc, topicsIds);
|
||||||
this.execute(command);
|
this.execute(command);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
shrinkBranch: function (topicsIds, collapse) {
|
shrinkBranch(topicsIds, collapse) {
|
||||||
$assert(topicsIds, 'topicsIds can not be null');
|
$assert(topicsIds, 'topicsIds can not be null');
|
||||||
|
|
||||||
var commandFunc = function (topic, isShrink) {
|
const commandFunc = function (topic, isShrink) {
|
||||||
topic.setChildrenShrunken(isShrink);
|
topic.setChildrenShrunken(isShrink);
|
||||||
return !isShrink;
|
return !isShrink;
|
||||||
};
|
};
|
||||||
|
|
||||||
var command = new GenericFunctionCommand(commandFunc, topicsIds, collapse);
|
const command = new GenericFunctionCommand(commandFunc, topicsIds, collapse);
|
||||||
this.execute(command, false);
|
this.execute(command, false);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
addFeatureToTopic: function (topicId, featureType, attributes) {
|
addFeatureToTopic(topicId, featureType, attributes) {
|
||||||
var command = new AddFeatureToTopicCommand(topicId, featureType, attributes);
|
const command = new AddFeatureToTopicCommand(topicId, featureType, attributes);
|
||||||
this.execute(command);
|
this.execute(command);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
changeFeatureToTopic: function (topicId, featureId, attributes) {
|
changeFeatureToTopic(topicId, featureId, attributes) {
|
||||||
var command = new ChangeFeatureToTopicCommand(topicId, featureId, attributes);
|
const command = new ChangeFeatureToTopicCommand(topicId, featureId, attributes);
|
||||||
this.execute(command);
|
this.execute(command);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
removeFeatureFromTopic: function (topicId, featureId) {
|
removeFeatureFromTopic(topicId, featureId) {
|
||||||
var command = new RemoveFeatureFromTopicCommand(topicId, featureId);
|
const command = new RemoveFeatureFromTopicCommand(topicId, featureId);
|
||||||
this.execute(command);
|
this.execute(command);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
execute: function (command) {
|
execute(command) {
|
||||||
this._actionRunner.execute(command);
|
this._actionRunner.execute(command);
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const CommandContext = new Class(
|
const CommandContext = new Class(
|
||||||
/** @lends CommandContext */ {
|
/** @lends CommandContext */ {
|
||||||
/**
|
/**
|
||||||
* @constructs
|
* @constructs
|
||||||
* @param {mindplot.Designer} designer
|
* @param {mindplot.Designer} designer
|
||||||
*/
|
*/
|
||||||
initialize: function (designer) {
|
initialize(designer) {
|
||||||
$assert(designer, 'designer can not be null');
|
$assert(designer, 'designer can not be null');
|
||||||
this._designer = designer;
|
this._designer = designer;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
findTopics: function (topicsIds) {
|
findTopics(topicsIds) {
|
||||||
$assert($defined(topicsIds), 'topicsIds can not be null');
|
$assert($defined(topicsIds), 'topicsIds can not be null');
|
||||||
if (!(topicsIds instanceof Array)) {
|
if (!(topicsIds instanceof Array)) {
|
||||||
topicsIds = [topicsIds];
|
topicsIds = [topicsIds];
|
||||||
}
|
}
|
||||||
|
|
||||||
var designerTopics = this._designer.getModel().getTopics();
|
const designerTopics = this._designer.getModel().getTopics();
|
||||||
var result = designerTopics.filter(function (topic) {
|
const result = designerTopics.filter((topic) => topicsIds.contains(topic.getId()));
|
||||||
return topicsIds.contains(topic.getId());
|
|
||||||
});
|
|
||||||
|
|
||||||
if (result.length != topicsIds.length) {
|
if (result.length != topicsIds.length) {
|
||||||
var ids = designerTopics.map(function (topic) {
|
const ids = designerTopics.map((topic) => topic.getId());
|
||||||
return topic.getId();
|
$assert(
|
||||||
});
|
result.length == topicsIds.length,
|
||||||
$assert(
|
`Could not find topic. Result:${
|
||||||
result.length == topicsIds.length,
|
result
|
||||||
'Could not find topic. Result:' +
|
}, Filter Criteria:${
|
||||||
result +
|
topicsIds
|
||||||
', Filter Criteria:' +
|
}, Current Topics: [${
|
||||||
topicsIds +
|
ids
|
||||||
', Current Topics: [' +
|
}]`,
|
||||||
ids +
|
);
|
||||||
']'
|
}
|
||||||
);
|
return result;
|
||||||
}
|
},
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
deleteTopic: function (topic) {
|
deleteTopic(topic) {
|
||||||
this._designer.removeTopic(topic);
|
this._designer.removeTopic(topic);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
createTopic: function (model) {
|
createTopic(model) {
|
||||||
$assert(model, 'model can not be null');
|
$assert(model, 'model can not be null');
|
||||||
return this._designer.nodeModelToNodeGraph(model);
|
return this._designer.nodeModelToNodeGraph(model);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
createModel: function () {
|
createModel() {
|
||||||
var mindmap = this._designer.getMindmap();
|
const mindmap = this._designer.getMindmap();
|
||||||
return mindmap.createNode(NodeModel.MAIN_TOPIC_TYPE);
|
return mindmap.createNode(NodeModel.MAIN_TOPIC_TYPE);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
addTopic: function (topic) {
|
addTopic(topic) {
|
||||||
var mindmap = this._designer.getMindmap();
|
const mindmap = this._designer.getMindmap();
|
||||||
return mindmap.addBranch(topic.getModel());
|
return mindmap.addBranch(topic.getModel());
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
connect: function (childTopic, parentTopic) {
|
connect(childTopic, parentTopic) {
|
||||||
childTopic.connectTo(parentTopic, this._designer._workspace);
|
childTopic.connectTo(parentTopic, this._designer._workspace);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
disconnect: function (topic) {
|
disconnect(topic) {
|
||||||
topic.disconnect(this._designer._workspace);
|
topic.disconnect(this._designer._workspace);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
addRelationship: function (model) {
|
addRelationship(model) {
|
||||||
$assert(model, 'model cannot be null');
|
$assert(model, 'model cannot be null');
|
||||||
return this._designer.addRelationship(model);
|
return this._designer.addRelationship(model);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
deleteRelationship: function (relationship) {
|
deleteRelationship(relationship) {
|
||||||
this._designer.deleteRelationship(relationship);
|
this._designer.deleteRelationship(relationship);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
findRelationships: function (relIds) {
|
findRelationships(relIds) {
|
||||||
$assert($defined(relIds), 'relId can not be null');
|
$assert($defined(relIds), 'relId can not be null');
|
||||||
if (!(relIds instanceof Array)) {
|
if (!(relIds instanceof Array)) {
|
||||||
relIds = [relIds];
|
relIds = [relIds];
|
||||||
}
|
}
|
||||||
|
|
||||||
var designerRel = this._designer.getModel().getRelationships();
|
const designerRel = this._designer.getModel().getRelationships();
|
||||||
return designerRel.filter(function (rel) {
|
return designerRel.filter((rel) => relIds.contains(rel.getId()));
|
||||||
return relIds.contains(rel.getId());
|
},
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
moveTopic: function (topic, position) {
|
moveTopic(topic, position) {
|
||||||
$assert(topic, 'topic cannot be null');
|
$assert(topic, 'topic cannot be null');
|
||||||
$assert(position, 'position cannot be null');
|
$assert(position, 'position cannot be null');
|
||||||
EventBus.instance.fireEvent(EventBus.events.NodeMoveEvent, {
|
EventBus.instance.fireEvent(EventBus.events.NodeMoveEvent, {
|
||||||
node: topic.getModel(),
|
node: topic.getModel(),
|
||||||
position: position,
|
position,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
export { StandaloneActionDispatcher, CommandContext };
|
export { StandaloneActionDispatcher, CommandContext };
|
||||||
|
@ -12,259 +12,249 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
const web2D = require('@wismapping/web2d')
|
const web2D = require('@wismapping/web2d');
|
||||||
const web2d = web2D()
|
|
||||||
|
|
||||||
const ActionDispatcher = require('./ActionDispatcher').default
|
const web2d = web2D();
|
||||||
|
|
||||||
//FIXME: Not used!
|
const ActionDispatcher = require('./ActionDispatcher').default;
|
||||||
|
|
||||||
|
// FIXME: Not used!
|
||||||
const TextEditor = new Class({
|
const TextEditor = new Class({
|
||||||
initialize: function (topic) {
|
initialize(topic) {
|
||||||
this._topic = topic;
|
this._topic = topic;
|
||||||
},
|
},
|
||||||
|
|
||||||
_buildEditor: function () {
|
_buildEditor() {
|
||||||
|
this._size = { width: 500, height: 100 };
|
||||||
|
const result = new Element('div');
|
||||||
|
result.setStyles({
|
||||||
|
position: 'absolute',
|
||||||
|
display: 'none',
|
||||||
|
zIndex: '8',
|
||||||
|
width: '500px',
|
||||||
|
height: '100px',
|
||||||
|
});
|
||||||
|
|
||||||
this._size = {width: 500, height: 100};
|
const inputContainer = new Element('div');
|
||||||
var result = new Element('div');
|
inputContainer.setStyles({
|
||||||
result.setStyles({
|
border: 'none',
|
||||||
position: "absolute",
|
overflow: 'auto',
|
||||||
display: "none",
|
});
|
||||||
zIndex: "8",
|
inputContainer.inject(result);
|
||||||
width: "500px",
|
|
||||||
height: "100px"
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
|
const inputText = new Element('input',
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
tabindex: '-1',
|
||||||
|
value: '',
|
||||||
|
});
|
||||||
|
inputText.setStyles({
|
||||||
|
border: 'none',
|
||||||
|
background: 'transparent',
|
||||||
|
});
|
||||||
|
inputText.inject(inputContainer);
|
||||||
|
|
||||||
var inputContainer = new Element('div');
|
const spanContainer = new Element('div');
|
||||||
inputContainer.setStyles({
|
spanContainer.setStyle('visibility', 'hidden');
|
||||||
border: "none",
|
spanContainer.inject(result);
|
||||||
overflow: "auto"
|
|
||||||
});
|
|
||||||
inputContainer.inject(result);
|
|
||||||
|
|
||||||
var inputText = new Element('input',
|
const spanElem = new Element('span', { tabindex: '-1' });
|
||||||
{
|
spanElem.setStyle('white-space', 'nowrap');
|
||||||
type: "text",
|
spanElem.setStyle('nowrap', 'nowrap');
|
||||||
tabindex: '-1',
|
spanElem.inject(spanContainer);
|
||||||
value: ""
|
|
||||||
}
|
|
||||||
);
|
|
||||||
inputText.setStyles({
|
|
||||||
border: "none",
|
|
||||||
background: "transparent"
|
|
||||||
});
|
|
||||||
inputText.inject(inputContainer);
|
|
||||||
|
|
||||||
var spanContainer = new Element('div');
|
return result;
|
||||||
spanContainer.setStyle('visibility', "hidden");
|
},
|
||||||
spanContainer.inject(result);
|
|
||||||
|
|
||||||
var spanElem = new Element('span', {tabindex: "-1"});
|
_registerEvents(divElem) {
|
||||||
spanElem.setStyle('white-space', "nowrap");
|
const inputElem = this._getTextareaElem();
|
||||||
spanElem.setStyle('nowrap', 'nowrap');
|
const spanElem = this._getSpanElem();
|
||||||
spanElem.inject(spanContainer);
|
const me = this;
|
||||||
|
|
||||||
|
divElem.addEvent('keydown', (event) => {
|
||||||
|
switch (event.key) {
|
||||||
|
case 'esc':
|
||||||
|
me.close(false);
|
||||||
|
break;
|
||||||
|
case 'enter':
|
||||||
|
me.close(true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
spanElem.innerHTML = inputElem.value;
|
||||||
|
var size = inputElem.value.length + 1;
|
||||||
|
inputElem.size = size;
|
||||||
|
if (spanElem.offsetWidth > (parseInt(divElem.style.width) - 100)) {
|
||||||
|
divElem.style.width = `${spanElem.offsetWidth + 100}px`;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
event.stopPropagation();
|
||||||
|
});
|
||||||
|
|
||||||
return result;
|
// If the user clicks on the input, all event must be ignored ...
|
||||||
},
|
divElem.addEvent('click', (event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
});
|
||||||
|
divElem.addEvent('dblclick', (event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
});
|
||||||
|
divElem.addEvent('mousedown', (event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
_registerEvents: function (divElem) {
|
isVisible() {
|
||||||
var inputElem = this._getTextareaElem();
|
return $defined(this._containerElem) && this._containerElem.getStyle('display') == 'block';
|
||||||
var spanElem = this._getSpanElem();
|
},
|
||||||
var me = this;
|
|
||||||
|
|
||||||
divElem.addEvent('keydown', function (event) {
|
_updateModel() {
|
||||||
switch (event.key) {
|
if (this._topic.getText() != this._getText()) {
|
||||||
case 'esc':
|
const text = this._getText();
|
||||||
me.close(false);
|
const topicId = this._topic.getId();
|
||||||
break;
|
|
||||||
case 'enter':
|
|
||||||
me.close(true);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
spanElem.innerHTML = inputElem.value;
|
|
||||||
var size = inputElem.value.length + 1;
|
|
||||||
inputElem.size = size;
|
|
||||||
if (spanElem.offsetWidth > (parseInt(divElem.style.width) - 100)) {
|
|
||||||
divElem.style.width = (spanElem.offsetWidth + 100) + "px";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
event.stopPropagation();
|
|
||||||
});
|
|
||||||
|
|
||||||
// If the user clicks on the input, all event must be ignored ...
|
const actionDispatcher = ActionDispatcher.getInstance();
|
||||||
divElem.addEvent('click', function (event) {
|
actionDispatcher.changeTextToTopic([topicId], text);
|
||||||
event.stopPropagation();
|
|
||||||
});
|
|
||||||
divElem.addEvent('dblclick', function (event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
});
|
|
||||||
divElem.addEvent('mousedown', function (event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
isVisible: function () {
|
|
||||||
return $defined(this._containerElem) && this._containerElem.getStyle('display') == 'block';
|
|
||||||
},
|
|
||||||
|
|
||||||
_updateModel: function () {
|
|
||||||
|
|
||||||
if (this._topic.getText() != this._getText()) {
|
|
||||||
var text = this._getText();
|
|
||||||
var topicId = this._topic.getId();
|
|
||||||
|
|
||||||
var actionDispatcher = ActionDispatcher.getInstance();
|
|
||||||
actionDispatcher.changeTextToTopic([topicId], text);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
show: function (text) {
|
|
||||||
|
|
||||||
if (!this.isVisible()) {
|
|
||||||
//Create editor ui
|
|
||||||
var editorElem = this._buildEditor();
|
|
||||||
editorElem.inject($(document.body)[0]);
|
|
||||||
|
|
||||||
this._containerElem = editorElem;
|
|
||||||
this._registerEvents(editorElem);
|
|
||||||
this._showEditor(text);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_showEditor: function (defaultText) {
|
|
||||||
|
|
||||||
var topic = this._topic;
|
|
||||||
|
|
||||||
// Hide topic text ...
|
|
||||||
topic.getTextShape().setVisibility(false);
|
|
||||||
|
|
||||||
// Set Editor Style
|
|
||||||
var nodeText = topic.getTextShape();
|
|
||||||
var font = nodeText.getFont();
|
|
||||||
font.size = nodeText.getHtmlFontSize();
|
|
||||||
font.color = nodeText.getColor();
|
|
||||||
this._setStyle(font);
|
|
||||||
|
|
||||||
// Set editor's initial text
|
|
||||||
var text = $defined(defaultText) ? defaultText : topic.getText();
|
|
||||||
this._setText(text);
|
|
||||||
|
|
||||||
var me = this;
|
|
||||||
// Set editor's initial size
|
|
||||||
var displayFunc = function () {
|
|
||||||
// Position the editor and set the size...
|
|
||||||
var textShape = me._topic.getTextShape();
|
|
||||||
|
|
||||||
me._containerElem.css('display', 'block');
|
|
||||||
|
|
||||||
me._containerElem.offset(textShape.getNativePosition());
|
|
||||||
// Set size ...
|
|
||||||
var elemSize = topic.getSize();
|
|
||||||
me._setEditorSize(elemSize.width, elemSize.height);
|
|
||||||
|
|
||||||
var textareaElem = me._getTextareaElem();
|
|
||||||
textareaElem.focus();
|
|
||||||
me._positionCursor(textareaElem, !$defined(defaultText));
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
displayFunc.delay(10);
|
|
||||||
},
|
|
||||||
|
|
||||||
_setStyle: function (fontStyle) {
|
|
||||||
var inputField = this._getTextareaElem();
|
|
||||||
var spanField = this._getSpanElem();
|
|
||||||
if (!$defined(fontStyle.font)) {
|
|
||||||
fontStyle.font = "Arial";
|
|
||||||
}
|
|
||||||
if (!$defined(fontStyle.style)) {
|
|
||||||
fontStyle.style = "normal";
|
|
||||||
}
|
|
||||||
if (!$defined(fontStyle.weight)) {
|
|
||||||
fontStyle.weight = "normal";
|
|
||||||
}
|
|
||||||
if (!$defined(fontStyle.size)) {
|
|
||||||
fontStyle.size = 12;
|
|
||||||
}
|
|
||||||
inputField.style.fontSize = fontStyle.size + "px";
|
|
||||||
inputField.style.fontFamily = fontStyle.font;
|
|
||||||
inputField.style.fontStyle = fontStyle.style;
|
|
||||||
inputField.style.fontWeight = fontStyle.weight;
|
|
||||||
inputField.style.color = fontStyle.color;
|
|
||||||
spanField.style.fontFamily = fontStyle.font;
|
|
||||||
spanField.style.fontStyle = fontStyle.style;
|
|
||||||
spanField.style.fontWeight = fontStyle.weight;
|
|
||||||
spanField.style.fontSize = fontStyle.size + "px";
|
|
||||||
},
|
|
||||||
|
|
||||||
_setText: function (text) {
|
|
||||||
var inputField = this._getTextareaElem();
|
|
||||||
inputField.size = text.length + 1;
|
|
||||||
this._containerElem.style.width = (inputField.size * parseInt(inputField.style.fontSize) + 100) + "px";
|
|
||||||
var spanField = this._getSpanElem();
|
|
||||||
spanField.innerHTML = text;
|
|
||||||
inputField.value = text;
|
|
||||||
},
|
|
||||||
|
|
||||||
_getText: function () {
|
|
||||||
return this._getTextareaElem().value;
|
|
||||||
},
|
|
||||||
|
|
||||||
_getTextareaElem: function () {
|
|
||||||
return this._containerElem.getElement('input');
|
|
||||||
},
|
|
||||||
|
|
||||||
_getSpanElem: function () {
|
|
||||||
return this._containerElem.getElement('span');
|
|
||||||
},
|
|
||||||
|
|
||||||
_setEditorSize: function (width, height) {
|
|
||||||
var textShape = this._topic.getTextShape();
|
|
||||||
var scale = web2d.utils.TransformUtil.workoutScale(textShape._peer);
|
|
||||||
this._size = {width: width * scale.width, height: height * scale.height};
|
|
||||||
this._containerElem.style.width = this._size.width * 2 + "px";
|
|
||||||
this._containerElem.style.height = this._size.height + "px";
|
|
||||||
},
|
|
||||||
|
|
||||||
_positionCursor: function (inputElem, selectText) {
|
|
||||||
// Select text if it's required ...
|
|
||||||
if (inputElem.createTextRange) //ie
|
|
||||||
{
|
|
||||||
var range = inputElem.createTextRange();
|
|
||||||
var pos = inputElem.value.length;
|
|
||||||
if (!selectText) {
|
|
||||||
range.select();
|
|
||||||
range.move("character", pos);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
range.move("character", pos);
|
|
||||||
range.select();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!selectText) {
|
|
||||||
inputElem.setSelectionRange(0, inputElem.value.length);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
close: function (update) {
|
|
||||||
if (this.isVisible()) {
|
|
||||||
// Update changes ...
|
|
||||||
if (!$defined(update) || update) {
|
|
||||||
this._updateModel();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Let make the visible text in the node visible again ...
|
|
||||||
this._topic.getTextShape().setVisibility(true);
|
|
||||||
|
|
||||||
// Remove it form the screen ...
|
|
||||||
this._containerElem.dispose();
|
|
||||||
this._containerElem = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
show(text) {
|
||||||
|
if (!this.isVisible()) {
|
||||||
|
// Create editor ui
|
||||||
|
const editorElem = this._buildEditor();
|
||||||
|
editorElem.inject($(document.body)[0]);
|
||||||
|
|
||||||
|
this._containerElem = editorElem;
|
||||||
|
this._registerEvents(editorElem);
|
||||||
|
this._showEditor(text);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_showEditor(defaultText) {
|
||||||
|
const topic = this._topic;
|
||||||
|
|
||||||
|
// Hide topic text ...
|
||||||
|
topic.getTextShape().setVisibility(false);
|
||||||
|
|
||||||
|
// Set Editor Style
|
||||||
|
const nodeText = topic.getTextShape();
|
||||||
|
const font = nodeText.getFont();
|
||||||
|
font.size = nodeText.getHtmlFontSize();
|
||||||
|
font.color = nodeText.getColor();
|
||||||
|
this._setStyle(font);
|
||||||
|
|
||||||
|
// Set editor's initial text
|
||||||
|
const text = $defined(defaultText) ? defaultText : topic.getText();
|
||||||
|
this._setText(text);
|
||||||
|
|
||||||
|
const me = this;
|
||||||
|
// Set editor's initial size
|
||||||
|
const displayFunc = function () {
|
||||||
|
// Position the editor and set the size...
|
||||||
|
const textShape = me._topic.getTextShape();
|
||||||
|
|
||||||
|
me._containerElem.css('display', 'block');
|
||||||
|
|
||||||
|
me._containerElem.offset(textShape.getNativePosition());
|
||||||
|
// Set size ...
|
||||||
|
const elemSize = topic.getSize();
|
||||||
|
me._setEditorSize(elemSize.width, elemSize.height);
|
||||||
|
|
||||||
|
const textareaElem = me._getTextareaElem();
|
||||||
|
textareaElem.focus();
|
||||||
|
me._positionCursor(textareaElem, !$defined(defaultText));
|
||||||
|
};
|
||||||
|
|
||||||
|
displayFunc.delay(10);
|
||||||
|
},
|
||||||
|
|
||||||
|
_setStyle(fontStyle) {
|
||||||
|
const inputField = this._getTextareaElem();
|
||||||
|
const spanField = this._getSpanElem();
|
||||||
|
if (!$defined(fontStyle.font)) {
|
||||||
|
fontStyle.font = 'Arial';
|
||||||
|
}
|
||||||
|
if (!$defined(fontStyle.style)) {
|
||||||
|
fontStyle.style = 'normal';
|
||||||
|
}
|
||||||
|
if (!$defined(fontStyle.weight)) {
|
||||||
|
fontStyle.weight = 'normal';
|
||||||
|
}
|
||||||
|
if (!$defined(fontStyle.size)) {
|
||||||
|
fontStyle.size = 12;
|
||||||
|
}
|
||||||
|
inputField.style.fontSize = `${fontStyle.size}px`;
|
||||||
|
inputField.style.fontFamily = fontStyle.font;
|
||||||
|
inputField.style.fontStyle = fontStyle.style;
|
||||||
|
inputField.style.fontWeight = fontStyle.weight;
|
||||||
|
inputField.style.color = fontStyle.color;
|
||||||
|
spanField.style.fontFamily = fontStyle.font;
|
||||||
|
spanField.style.fontStyle = fontStyle.style;
|
||||||
|
spanField.style.fontWeight = fontStyle.weight;
|
||||||
|
spanField.style.fontSize = `${fontStyle.size}px`;
|
||||||
|
},
|
||||||
|
|
||||||
|
_setText(text) {
|
||||||
|
const inputField = this._getTextareaElem();
|
||||||
|
inputField.size = text.length + 1;
|
||||||
|
this._containerElem.style.width = `${inputField.size * parseInt(inputField.style.fontSize) + 100}px`;
|
||||||
|
const spanField = this._getSpanElem();
|
||||||
|
spanField.innerHTML = text;
|
||||||
|
inputField.value = text;
|
||||||
|
},
|
||||||
|
|
||||||
|
_getText() {
|
||||||
|
return this._getTextareaElem().value;
|
||||||
|
},
|
||||||
|
|
||||||
|
_getTextareaElem() {
|
||||||
|
return this._containerElem.getElement('input');
|
||||||
|
},
|
||||||
|
|
||||||
|
_getSpanElem() {
|
||||||
|
return this._containerElem.getElement('span');
|
||||||
|
},
|
||||||
|
|
||||||
|
_setEditorSize(width, height) {
|
||||||
|
const textShape = this._topic.getTextShape();
|
||||||
|
const scale = web2d.utils.TransformUtil.workoutScale(textShape._peer);
|
||||||
|
this._size = { width: width * scale.width, height: height * scale.height };
|
||||||
|
this._containerElem.style.width = `${this._size.width * 2}px`;
|
||||||
|
this._containerElem.style.height = `${this._size.height}px`;
|
||||||
|
},
|
||||||
|
|
||||||
|
_positionCursor(inputElem, selectText) {
|
||||||
|
// Select text if it's required ...
|
||||||
|
if (inputElem.createTextRange) // ie
|
||||||
|
{
|
||||||
|
const range = inputElem.createTextRange();
|
||||||
|
const pos = inputElem.value.length;
|
||||||
|
if (!selectText) {
|
||||||
|
range.select();
|
||||||
|
range.move('character', pos);
|
||||||
|
} else {
|
||||||
|
range.move('character', pos);
|
||||||
|
range.select();
|
||||||
|
}
|
||||||
|
} else if (!selectText) {
|
||||||
|
inputElem.setSelectionRange(0, inputElem.value.length);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
close(update) {
|
||||||
|
if (this.isVisible()) {
|
||||||
|
// Update changes ...
|
||||||
|
if (!$defined(update) || update) {
|
||||||
|
this._updateModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let make the visible text in the node visible again ...
|
||||||
|
this._topic.getTextShape().setVisibility(true);
|
||||||
|
|
||||||
|
// Remove it form the screen ...
|
||||||
|
this._containerElem.dispose();
|
||||||
|
this._containerElem = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default TextEditor;
|
export default TextEditor;
|
||||||
|
@ -20,11 +20,11 @@ const TextEditor = require('./TextEditor').default;
|
|||||||
const TextEditorFactory = {};
|
const TextEditorFactory = {};
|
||||||
|
|
||||||
TextEditorFactory.getTextEditorFromName = function (name) {
|
TextEditorFactory.getTextEditorFromName = function (name) {
|
||||||
var editorClass = null;
|
let editorClass = null;
|
||||||
if (name == 'RichTextEditor') {
|
if (name == 'RichTextEditor') {
|
||||||
editorClass = RichTextEditor;
|
editorClass = RichTextEditor;
|
||||||
} else {
|
} else {
|
||||||
editorClass = TextEditor;
|
editorClass = TextEditor;
|
||||||
}
|
}
|
||||||
return editorClass;
|
return editorClass;
|
||||||
};
|
};
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -20,66 +20,66 @@ const MultilineTextEditor = require('./MultilineTextEditor').default;
|
|||||||
const { TopicShape } = require('./model/INodeModel');
|
const { TopicShape } = require('./model/INodeModel');
|
||||||
|
|
||||||
const TopicEventDispatcher = new Class({
|
const TopicEventDispatcher = new Class({
|
||||||
Extends: Events,
|
Extends: Events,
|
||||||
Static: {
|
Static: {
|
||||||
_instance: null,
|
_instance: null,
|
||||||
|
|
||||||
configure: function (readOnly) {
|
configure(readOnly) {
|
||||||
this._instance = new TopicEventDispatcher(readOnly);
|
this._instance = new TopicEventDispatcher(readOnly);
|
||||||
},
|
|
||||||
|
|
||||||
getInstance: function () {
|
|
||||||
return this._instance;
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize: function (readOnly) {
|
getInstance() {
|
||||||
this._readOnly = readOnly;
|
return this._instance;
|
||||||
this._activeEditor = null;
|
|
||||||
this._multilineEditor = new MultilineTextEditor();
|
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
|
||||||
close: function (update) {
|
initialize(readOnly) {
|
||||||
if (this.isVisible()) {
|
this._readOnly = readOnly;
|
||||||
this._activeEditor.close(update);
|
this._activeEditor = null;
|
||||||
this._activeEditor = null;
|
this._multilineEditor = new MultilineTextEditor();
|
||||||
}
|
},
|
||||||
},
|
|
||||||
|
|
||||||
show: function (topic, options) {
|
close(update) {
|
||||||
this.process(TopicEvent.EDIT, topic, options);
|
if (this.isVisible()) {
|
||||||
},
|
this._activeEditor.close(update);
|
||||||
|
this._activeEditor = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
process: function (eventType, topic, options) {
|
show(topic, options) {
|
||||||
$assert(eventType, 'eventType can not be null');
|
this.process(TopicEvent.EDIT, topic, options);
|
||||||
|
},
|
||||||
|
|
||||||
// Close all previous open editor ....
|
process(eventType, topic, options) {
|
||||||
if (this.isVisible()) {
|
$assert(eventType, 'eventType can not be null');
|
||||||
this.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open the new editor ...
|
// Close all previous open editor ....
|
||||||
var model = topic.getModel();
|
if (this.isVisible()) {
|
||||||
if (
|
this.close();
|
||||||
model.getShapeType() != TopicShape.IMAGE &&
|
}
|
||||||
!this._readOnly &&
|
|
||||||
eventType == TopicEvent.EDIT
|
|
||||||
) {
|
|
||||||
this._multilineEditor.show(topic, options ? options.text : null);
|
|
||||||
this._activeEditor = this._multilineEditor;
|
|
||||||
} else {
|
|
||||||
this.fireEvent(eventType, { model: model, readOnly: this._readOnly });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
isVisible: function () {
|
// Open the new editor ...
|
||||||
return this._activeEditor != null && this._activeEditor.isVisible();
|
const model = topic.getModel();
|
||||||
},
|
if (
|
||||||
|
model.getShapeType() != TopicShape.IMAGE
|
||||||
|
&& !this._readOnly
|
||||||
|
&& eventType == TopicEvent.EDIT
|
||||||
|
) {
|
||||||
|
this._multilineEditor.show(topic, options ? options.text : null);
|
||||||
|
this._activeEditor = this._multilineEditor;
|
||||||
|
} else {
|
||||||
|
this.fireEvent(eventType, { model, readOnly: this._readOnly });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
isVisible() {
|
||||||
|
return this._activeEditor != null && this._activeEditor.isVisible();
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const TopicEvent = {
|
const TopicEvent = {
|
||||||
EDIT: 'editnode',
|
EDIT: 'editnode',
|
||||||
CLICK: 'clicknode',
|
CLICK: 'clicknode',
|
||||||
};
|
};
|
||||||
|
|
||||||
export { TopicEvent };
|
export { TopicEvent };
|
||||||
|
@ -25,38 +25,36 @@ const NoteModel = require('./model/NoteModel').default;
|
|||||||
const NoteIcon = require('./NoteIcon').default;
|
const NoteIcon = require('./NoteIcon').default;
|
||||||
|
|
||||||
const TopicFeature = {
|
const TopicFeature = {
|
||||||
/** the icon object */
|
/** the icon object */
|
||||||
Icon: {
|
Icon: {
|
||||||
id: IconModel.FEATURE_TYPE,
|
id: IconModel.FEATURE_TYPE,
|
||||||
model: IconModel,
|
model: IconModel,
|
||||||
icon: ImageIcon
|
icon: ImageIcon,
|
||||||
},
|
},
|
||||||
|
|
||||||
/** the link object */
|
/** the link object */
|
||||||
Link: {
|
Link: {
|
||||||
id: LinkModel.FEATURE_TYPE,
|
id: LinkModel.FEATURE_TYPE,
|
||||||
model: LinkModel,
|
model: LinkModel,
|
||||||
icon: LinkIcon
|
icon: LinkIcon,
|
||||||
},
|
},
|
||||||
|
|
||||||
/** the note object */
|
/** the note object */
|
||||||
Note: {
|
Note: {
|
||||||
id: NoteModel.FEATURE_TYPE,
|
id: NoteModel.FEATURE_TYPE,
|
||||||
model: NoteModel,
|
model: NoteModel,
|
||||||
icon: NoteIcon
|
icon: NoteIcon,
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param id the feature metadata id
|
* @param id the feature metadata id
|
||||||
* @return {Boolean} returns true if the given id is contained in the metadata array
|
* @return {Boolean} returns true if the given id is contained in the metadata array
|
||||||
*/
|
*/
|
||||||
isSupported: function (id) {
|
isSupported(id) {
|
||||||
return TopicFeature._featuresMetadataById.some(function (elem) {
|
return TopicFeature._featuresMetadataById.some((elem) => elem.id == id);
|
||||||
return elem.id == id;
|
},
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param type
|
* @param type
|
||||||
* @param attributes
|
* @param attributes
|
||||||
* @throws will throw an error if type is null or undefined
|
* @throws will throw an error if type is null or undefined
|
||||||
@ -64,17 +62,15 @@ const TopicFeature = {
|
|||||||
* @return {mindplot.model.FeatureModel} a new instance of the feature model subclass matching
|
* @return {mindplot.model.FeatureModel} a new instance of the feature model subclass matching
|
||||||
* the topic feature
|
* the topic feature
|
||||||
*/
|
*/
|
||||||
createModel: function (type, attributes) {
|
createModel(type, attributes) {
|
||||||
$assert(type, 'type can not be null');
|
$assert(type, 'type can not be null');
|
||||||
$assert(attributes, 'attributes can not be null');
|
$assert(attributes, 'attributes can not be null');
|
||||||
|
|
||||||
var model = TopicFeature._featuresMetadataById.filter(function (elem) {
|
const { model } = TopicFeature._featuresMetadataById.filter((elem) => elem.id == type)[0];
|
||||||
return elem.id == type;
|
return new model(attributes);
|
||||||
})[0].model;
|
},
|
||||||
return new model(attributes);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {mindplot.Topic} topic
|
* @param {mindplot.Topic} topic
|
||||||
* @param {mindplot.model.FeatureModel} model
|
* @param {mindplot.model.FeatureModel} model
|
||||||
* @param {Boolean} readOnly true if the editor is running in read-only mode
|
* @param {Boolean} readOnly true if the editor is running in read-only mode
|
||||||
@ -82,15 +78,13 @@ const TopicFeature = {
|
|||||||
* @throws will throw an error if model is null or undefined
|
* @throws will throw an error if model is null or undefined
|
||||||
* @return {mindplot.Icon} a new instance of the icon subclass matching the topic feature
|
* @return {mindplot.Icon} a new instance of the icon subclass matching the topic feature
|
||||||
*/
|
*/
|
||||||
createIcon: function (topic, model, readOnly) {
|
createIcon(topic, model, readOnly) {
|
||||||
$assert(topic, 'topic can not be null');
|
$assert(topic, 'topic can not be null');
|
||||||
$assert(model, 'model can not be null');
|
$assert(model, 'model can not be null');
|
||||||
|
|
||||||
var icon = TopicFeature._featuresMetadataById.filter(function (elem) {
|
const { icon } = TopicFeature._featuresMetadataById.filter((elem) => elem.id == model.getType())[0];
|
||||||
return elem.id == model.getType();
|
return new icon(topic, model, readOnly);
|
||||||
})[0].icon;
|
},
|
||||||
return new icon(topic, model, readOnly);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TopicFeature._featuresMetadataById = [TopicFeature.Icon, TopicFeature.Link, TopicFeature.Note];
|
TopicFeature._featuresMetadataById = [TopicFeature.Icon, TopicFeature.Link, TopicFeature.Note];
|
||||||
|
@ -18,115 +18,115 @@
|
|||||||
const { TopicShape } = require('./model/INodeModel');
|
const { TopicShape } = require('./model/INodeModel');
|
||||||
|
|
||||||
const TopicStyle = new Class({
|
const TopicStyle = new Class({
|
||||||
Static: {
|
Static: {
|
||||||
_getStyles: function (topic) {
|
_getStyles(topic) {
|
||||||
$assert(topic, 'topic can not be null');
|
$assert(topic, 'topic can not be null');
|
||||||
|
|
||||||
var result;
|
let result;
|
||||||
if (topic.isCentralTopic()) {
|
if (topic.isCentralTopic()) {
|
||||||
result = TopicStyle.STYLES.CENTRAL_TOPIC;
|
result = TopicStyle.STYLES.CENTRAL_TOPIC;
|
||||||
} else {
|
} else {
|
||||||
var targetTopic = topic.getOutgoingConnectedTopic();
|
const targetTopic = topic.getOutgoingConnectedTopic();
|
||||||
if ($defined(targetTopic)) {
|
if ($defined(targetTopic)) {
|
||||||
if (targetTopic.isCentralTopic()) {
|
if (targetTopic.isCentralTopic()) {
|
||||||
result = TopicStyle.STYLES.MAIN_TOPIC;
|
result = TopicStyle.STYLES.MAIN_TOPIC;
|
||||||
} else {
|
} else {
|
||||||
result = TopicStyle.STYLES.SUB_TOPIC;
|
result = TopicStyle.STYLES.SUB_TOPIC;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result = TopicStyle.STYLES.ISOLATED_TOPIC;
|
result = TopicStyle.STYLES.ISOLATED_TOPIC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
},
|
|
||||||
|
|
||||||
defaultText: function (topic) {
|
|
||||||
var msgKey = this._getStyles(topic).msgKey;
|
|
||||||
return $msg(msgKey);
|
|
||||||
},
|
|
||||||
|
|
||||||
defaultFontStyle: function (topic) {
|
|
||||||
return this._getStyles(topic).fontStyle;
|
|
||||||
},
|
|
||||||
|
|
||||||
defaultBackgroundColor: function (topic) {
|
|
||||||
return this._getStyles(topic).backgroundColor;
|
|
||||||
},
|
|
||||||
|
|
||||||
defaultBorderColor: function (topic) {
|
|
||||||
return this._getStyles(topic).borderColor;
|
|
||||||
},
|
|
||||||
|
|
||||||
getInnerPadding: function (topic) {
|
|
||||||
return this._getStyles(topic).innerPadding;
|
|
||||||
},
|
|
||||||
|
|
||||||
defaultShapeType: function (topic) {
|
|
||||||
return this._getStyles(topic).shapeType;
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
defaultText(topic) {
|
||||||
|
const { msgKey } = this._getStyles(topic);
|
||||||
|
return $msg(msgKey);
|
||||||
|
},
|
||||||
|
|
||||||
|
defaultFontStyle(topic) {
|
||||||
|
return this._getStyles(topic).fontStyle;
|
||||||
|
},
|
||||||
|
|
||||||
|
defaultBackgroundColor(topic) {
|
||||||
|
return this._getStyles(topic).backgroundColor;
|
||||||
|
},
|
||||||
|
|
||||||
|
defaultBorderColor(topic) {
|
||||||
|
return this._getStyles(topic).borderColor;
|
||||||
|
},
|
||||||
|
|
||||||
|
getInnerPadding(topic) {
|
||||||
|
return this._getStyles(topic).innerPadding;
|
||||||
|
},
|
||||||
|
|
||||||
|
defaultShapeType(topic) {
|
||||||
|
return this._getStyles(topic).shapeType;
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
TopicStyle.STYLES = {
|
TopicStyle.STYLES = {
|
||||||
CENTRAL_TOPIC: {
|
CENTRAL_TOPIC: {
|
||||||
borderColor: 'rgb(57,113,177)',
|
borderColor: 'rgb(57,113,177)',
|
||||||
backgroundColor: 'rgb(80,157,192)',
|
backgroundColor: 'rgb(80,157,192)',
|
||||||
fontStyle: {
|
fontStyle: {
|
||||||
font: 'Verdana',
|
font: 'Verdana',
|
||||||
size: 10,
|
size: 10,
|
||||||
style: 'normal',
|
style: 'normal',
|
||||||
weight: 'bold',
|
weight: 'bold',
|
||||||
color: '#ffffff',
|
color: '#ffffff',
|
||||||
},
|
|
||||||
msgKey: 'CENTRAL_TOPIC',
|
|
||||||
innerPadding: 11,
|
|
||||||
shapeType: TopicShape.ROUNDED_RECT,
|
|
||||||
},
|
},
|
||||||
|
msgKey: 'CENTRAL_TOPIC',
|
||||||
|
innerPadding: 11,
|
||||||
|
shapeType: TopicShape.ROUNDED_RECT,
|
||||||
|
},
|
||||||
|
|
||||||
MAIN_TOPIC: {
|
MAIN_TOPIC: {
|
||||||
borderColor: 'rgb(2,59,185)',
|
borderColor: 'rgb(2,59,185)',
|
||||||
backgroundColor: 'rgb(224,229,239)',
|
backgroundColor: 'rgb(224,229,239)',
|
||||||
fontStyle: {
|
fontStyle: {
|
||||||
font: 'Arial',
|
font: 'Arial',
|
||||||
size: 8,
|
size: 8,
|
||||||
style: 'normal',
|
style: 'normal',
|
||||||
weight: 'normal',
|
weight: 'normal',
|
||||||
color: 'rgb(82,92,97)',
|
color: 'rgb(82,92,97)',
|
||||||
},
|
|
||||||
msgKey: 'MAIN_TOPIC',
|
|
||||||
innerPadding: 3,
|
|
||||||
shapeType: TopicShape.LINE,
|
|
||||||
},
|
},
|
||||||
|
msgKey: 'MAIN_TOPIC',
|
||||||
|
innerPadding: 3,
|
||||||
|
shapeType: TopicShape.LINE,
|
||||||
|
},
|
||||||
|
|
||||||
SUB_TOPIC: {
|
SUB_TOPIC: {
|
||||||
borderColor: 'rgb(2,59,185)',
|
borderColor: 'rgb(2,59,185)',
|
||||||
backgroundColor: 'rgb(224,229,239)',
|
backgroundColor: 'rgb(224,229,239)',
|
||||||
fontStyle: {
|
fontStyle: {
|
||||||
font: 'Arial',
|
font: 'Arial',
|
||||||
size: 6,
|
size: 6,
|
||||||
style: 'normal',
|
style: 'normal',
|
||||||
weight: 'normal',
|
weight: 'normal',
|
||||||
color: 'rgb(82,92,97)',
|
color: 'rgb(82,92,97)',
|
||||||
},
|
|
||||||
msgKey: 'SUB_TOPIC',
|
|
||||||
innerPadding: 3,
|
|
||||||
shapeType: TopicShape.LINE,
|
|
||||||
},
|
},
|
||||||
|
msgKey: 'SUB_TOPIC',
|
||||||
|
innerPadding: 3,
|
||||||
|
shapeType: TopicShape.LINE,
|
||||||
|
},
|
||||||
|
|
||||||
ISOLATED_TOPIC: {
|
ISOLATED_TOPIC: {
|
||||||
borderColor: 'rgb(2,59,185)',
|
borderColor: 'rgb(2,59,185)',
|
||||||
backgroundColor: 'rgb(224,229,239)',
|
backgroundColor: 'rgb(224,229,239)',
|
||||||
fontStyle: {
|
fontStyle: {
|
||||||
font: 'Verdana',
|
font: 'Verdana',
|
||||||
size: 8,
|
size: 8,
|
||||||
style: 'normal',
|
style: 'normal',
|
||||||
weight: 'normal',
|
weight: 'normal',
|
||||||
color: 'rgb(82,92,97)',
|
color: 'rgb(82,92,97)',
|
||||||
},
|
|
||||||
msgKey: 'ISOLATED_TOPIC',
|
|
||||||
innerPadding: 4,
|
|
||||||
shapeType: TopicShape.LINE,
|
|
||||||
},
|
},
|
||||||
|
msgKey: 'ISOLATED_TOPIC',
|
||||||
|
innerPadding: 4,
|
||||||
|
shapeType: TopicShape.LINE,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default TopicStyle;
|
export default TopicStyle;
|
||||||
|
@ -15,215 +15,212 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
const web2D = require('@wismapping/web2d')
|
const web2D = require('@wismapping/web2d');
|
||||||
|
|
||||||
const web2d = web2D();
|
const web2d = web2D();
|
||||||
|
|
||||||
const Workspace = new Class({
|
const Workspace = new Class({
|
||||||
initialize: function (screenManager, zoom) {
|
initialize(screenManager, zoom) {
|
||||||
// Create a suitable container ...
|
// Create a suitable container ...
|
||||||
$assert(screenManager, 'Div container can not be null');
|
$assert(screenManager, 'Div container can not be null');
|
||||||
$assert(zoom, 'zoom container can not be null');
|
$assert(zoom, 'zoom container can not be null');
|
||||||
|
|
||||||
this._zoom = zoom;
|
this._zoom = zoom;
|
||||||
this._screenManager = screenManager;
|
this._screenManager = screenManager;
|
||||||
|
|
||||||
var divContainer = screenManager.getContainer();
|
const divContainer = screenManager.getContainer();
|
||||||
this._screenWidth = parseInt(divContainer.css('width'));
|
this._screenWidth = parseInt(divContainer.css('width'));
|
||||||
this._screenHeight = parseInt(divContainer.css('height'));
|
this._screenHeight = parseInt(divContainer.css('height'));
|
||||||
|
|
||||||
// Initialize web2d workspace.
|
// Initialize web2d workspace.
|
||||||
var workspace = this._createWorkspace();
|
const workspace = this._createWorkspace();
|
||||||
this._workspace = workspace;
|
this._workspace = workspace;
|
||||||
|
|
||||||
// Append to the workspace...
|
// Append to the workspace...
|
||||||
workspace.addItAsChildTo(divContainer);
|
workspace.addItAsChildTo(divContainer);
|
||||||
this.setZoom(zoom, true);
|
this.setZoom(zoom, true);
|
||||||
|
|
||||||
// Register drag events ...
|
// Register drag events ...
|
||||||
this._registerDragEvents();
|
this._registerDragEvents();
|
||||||
this._eventsEnabled = true;
|
this._eventsEnabled = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
_createWorkspace: function () {
|
_createWorkspace() {
|
||||||
// Initialize workspace ...
|
// Initialize workspace ...
|
||||||
var coordOriginX = -(this._screenWidth / 2);
|
const coordOriginX = -(this._screenWidth / 2);
|
||||||
var coordOriginY = -(this._screenHeight / 2);
|
const coordOriginY = -(this._screenHeight / 2);
|
||||||
|
|
||||||
var workspaceProfile = {
|
const workspaceProfile = {
|
||||||
width: this._screenWidth + "px",
|
width: `${this._screenWidth}px`,
|
||||||
height: this._screenHeight + "px",
|
height: `${this._screenHeight}px`,
|
||||||
coordSizeWidth: this._screenWidth,
|
coordSizeWidth: this._screenWidth,
|
||||||
coordSizeHeight: this._screenHeight,
|
coordSizeHeight: this._screenHeight,
|
||||||
coordOriginX: coordOriginX,
|
coordOriginX,
|
||||||
coordOriginY: coordOriginY,
|
coordOriginY,
|
||||||
fillColor: 'transparent',
|
fillColor: 'transparent',
|
||||||
strokeWidth: 0
|
strokeWidth: 0,
|
||||||
};
|
};
|
||||||
web2d.Toolkit.init();
|
web2d.Toolkit.init();
|
||||||
return new web2d.Workspace(workspaceProfile);
|
return new web2d.Workspace(workspaceProfile);
|
||||||
},
|
},
|
||||||
|
|
||||||
append: function (shape) {
|
append(shape) {
|
||||||
if ($defined(shape.addToWorkspace)) {
|
if ($defined(shape.addToWorkspace)) {
|
||||||
shape.addToWorkspace(this);
|
shape.addToWorkspace(this);
|
||||||
} else {
|
} else {
|
||||||
this._workspace.append(shape);
|
this._workspace.append(shape);
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
removeChild: function (shape) {
|
|
||||||
// Element is a node, not a web2d element?
|
|
||||||
if ($defined(shape.removeFromWorkspace)) {
|
|
||||||
shape.removeFromWorkspace(this);
|
|
||||||
} else {
|
|
||||||
this._workspace.removeChild(shape);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
addEvent: function (type, listener) {
|
|
||||||
this._workspace.addEvent(type, listener);
|
|
||||||
},
|
|
||||||
|
|
||||||
removeEvent: function (type, listener) {
|
|
||||||
$assert(type, 'type can not be null');
|
|
||||||
$assert(listener, 'listener can not be null');
|
|
||||||
this._workspace.removeEvent(type, listener);
|
|
||||||
},
|
|
||||||
|
|
||||||
getSize: function () {
|
|
||||||
return this._workspace.getCoordSize();
|
|
||||||
},
|
|
||||||
|
|
||||||
setZoom: function (zoom, center) {
|
|
||||||
this._zoom = zoom;
|
|
||||||
var workspace = this._workspace;
|
|
||||||
|
|
||||||
// Update coord scale...
|
|
||||||
var coordWidth = zoom * this._screenWidth;
|
|
||||||
var coordHeight = zoom * this._screenHeight;
|
|
||||||
workspace.setCoordSize(coordWidth, coordHeight);
|
|
||||||
|
|
||||||
// View port coords ...
|
|
||||||
if (this._viewPort) {
|
|
||||||
this._viewPort.width = this._viewPort.width * zoom;
|
|
||||||
this._viewPort.height = this._viewPort.height * zoom;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Center topic....
|
|
||||||
var coordOriginX;
|
|
||||||
var coordOriginY;
|
|
||||||
|
|
||||||
if (center) {
|
|
||||||
if (this._viewPort) {
|
|
||||||
coordOriginX = -(this._viewPort.width / 2);
|
|
||||||
coordOriginY = -(this._viewPort.height / 2);
|
|
||||||
} else {
|
|
||||||
coordOriginX = -(coordWidth / 2);
|
|
||||||
coordOriginY = -(coordHeight / 2);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
var coordOrigin = workspace.getCoordOrigin();
|
|
||||||
coordOriginX = coordOrigin.x;
|
|
||||||
coordOriginY = coordOrigin.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
workspace.setCoordOrigin(coordOriginX, coordOriginY);
|
|
||||||
|
|
||||||
// Update screen.
|
|
||||||
this._screenManager.setOffset(coordOriginX, coordOriginY);
|
|
||||||
this._screenManager.setScale(zoom);
|
|
||||||
|
|
||||||
// Some changes in the screen. Let's fire an update event...
|
|
||||||
this._screenManager.fireEvent('update');
|
|
||||||
},
|
|
||||||
|
|
||||||
getScreenManager: function () {
|
|
||||||
return this._screenManager;
|
|
||||||
},
|
|
||||||
|
|
||||||
enableWorkspaceEvents: function (value) {
|
|
||||||
this._eventsEnabled = value;
|
|
||||||
},
|
|
||||||
|
|
||||||
isWorkspaceEventsEnabled: function () {
|
|
||||||
return this._eventsEnabled;
|
|
||||||
},
|
|
||||||
|
|
||||||
dumpNativeChart: function () {
|
|
||||||
return this._workspace.dumpNativeChart();
|
|
||||||
},
|
|
||||||
|
|
||||||
_registerDragEvents: function () {
|
|
||||||
var workspace = this._workspace;
|
|
||||||
var screenManager = this._screenManager;
|
|
||||||
var mWorkspace = this;
|
|
||||||
var mouseDownListener = function (event) {
|
|
||||||
if (!$defined(workspace._mouseMoveListener)) {
|
|
||||||
if (mWorkspace.isWorkspaceEventsEnabled()) {
|
|
||||||
mWorkspace.enableWorkspaceEvents(false);
|
|
||||||
|
|
||||||
var mouseDownPosition = screenManager.getWorkspaceMousePosition(event);
|
|
||||||
var originalCoordOrigin = workspace.getCoordOrigin();
|
|
||||||
|
|
||||||
var wasDragged = false;
|
|
||||||
workspace._mouseMoveListener = function (event) {
|
|
||||||
|
|
||||||
var currentMousePosition = screenManager.getWorkspaceMousePosition(event);
|
|
||||||
|
|
||||||
var offsetX = currentMousePosition.x - mouseDownPosition.x;
|
|
||||||
var coordOriginX = -offsetX + originalCoordOrigin.x;
|
|
||||||
|
|
||||||
var offsetY = currentMousePosition.y - mouseDownPosition.y;
|
|
||||||
var coordOriginY = -offsetY + originalCoordOrigin.y;
|
|
||||||
|
|
||||||
workspace.setCoordOrigin(coordOriginX, coordOriginY);
|
|
||||||
|
|
||||||
// Change cursor.
|
|
||||||
if (Browser.firefox) {
|
|
||||||
window.document.body.style.cursor = "-moz-grabbing";
|
|
||||||
} else {
|
|
||||||
window.document.body.style.cursor = "move";
|
|
||||||
}
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
// Fire drag event ...
|
|
||||||
screenManager.fireEvent('update');
|
|
||||||
wasDragged = true;
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
||||||
screenManager.addEvent('mousemove', workspace._mouseMoveListener);
|
|
||||||
|
|
||||||
// Register mouse up listeners ...
|
|
||||||
workspace._mouseUpListener = function (event) {
|
|
||||||
|
|
||||||
screenManager.removeEvent('mousemove', workspace._mouseMoveListener);
|
|
||||||
screenManager.removeEvent('mouseup', workspace._mouseUpListener);
|
|
||||||
workspace._mouseUpListener = null;
|
|
||||||
workspace._mouseMoveListener = null;
|
|
||||||
window.document.body.style.cursor = 'default';
|
|
||||||
|
|
||||||
// Update screen manager offset.
|
|
||||||
var coordOrigin = workspace.getCoordOrigin();
|
|
||||||
screenManager.setOffset(coordOrigin.x, coordOrigin.y);
|
|
||||||
mWorkspace.enableWorkspaceEvents(true);
|
|
||||||
|
|
||||||
if (!wasDragged) {
|
|
||||||
screenManager.fireEvent('click');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
screenManager.addEvent('mouseup', workspace._mouseUpListener);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
workspace._mouseUpListener();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
screenManager.addEvent('mousedown', mouseDownListener);
|
|
||||||
},
|
|
||||||
|
|
||||||
setViewPort: function (size) {
|
|
||||||
this._viewPort = size;
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
removeChild(shape) {
|
||||||
|
// Element is a node, not a web2d element?
|
||||||
|
if ($defined(shape.removeFromWorkspace)) {
|
||||||
|
shape.removeFromWorkspace(this);
|
||||||
|
} else {
|
||||||
|
this._workspace.removeChild(shape);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
addEvent(type, listener) {
|
||||||
|
this._workspace.addEvent(type, listener);
|
||||||
|
},
|
||||||
|
|
||||||
|
removeEvent(type, listener) {
|
||||||
|
$assert(type, 'type can not be null');
|
||||||
|
$assert(listener, 'listener can not be null');
|
||||||
|
this._workspace.removeEvent(type, listener);
|
||||||
|
},
|
||||||
|
|
||||||
|
getSize() {
|
||||||
|
return this._workspace.getCoordSize();
|
||||||
|
},
|
||||||
|
|
||||||
|
setZoom(zoom, center) {
|
||||||
|
this._zoom = zoom;
|
||||||
|
const workspace = this._workspace;
|
||||||
|
|
||||||
|
// Update coord scale...
|
||||||
|
const coordWidth = zoom * this._screenWidth;
|
||||||
|
const coordHeight = zoom * this._screenHeight;
|
||||||
|
workspace.setCoordSize(coordWidth, coordHeight);
|
||||||
|
|
||||||
|
// View port coords ...
|
||||||
|
if (this._viewPort) {
|
||||||
|
this._viewPort.width = this._viewPort.width * zoom;
|
||||||
|
this._viewPort.height = this._viewPort.height * zoom;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Center topic....
|
||||||
|
let coordOriginX;
|
||||||
|
let coordOriginY;
|
||||||
|
|
||||||
|
if (center) {
|
||||||
|
if (this._viewPort) {
|
||||||
|
coordOriginX = -(this._viewPort.width / 2);
|
||||||
|
coordOriginY = -(this._viewPort.height / 2);
|
||||||
|
} else {
|
||||||
|
coordOriginX = -(coordWidth / 2);
|
||||||
|
coordOriginY = -(coordHeight / 2);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const coordOrigin = workspace.getCoordOrigin();
|
||||||
|
coordOriginX = coordOrigin.x;
|
||||||
|
coordOriginY = coordOrigin.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
workspace.setCoordOrigin(coordOriginX, coordOriginY);
|
||||||
|
|
||||||
|
// Update screen.
|
||||||
|
this._screenManager.setOffset(coordOriginX, coordOriginY);
|
||||||
|
this._screenManager.setScale(zoom);
|
||||||
|
|
||||||
|
// Some changes in the screen. Let's fire an update event...
|
||||||
|
this._screenManager.fireEvent('update');
|
||||||
|
},
|
||||||
|
|
||||||
|
getScreenManager() {
|
||||||
|
return this._screenManager;
|
||||||
|
},
|
||||||
|
|
||||||
|
enableWorkspaceEvents(value) {
|
||||||
|
this._eventsEnabled = value;
|
||||||
|
},
|
||||||
|
|
||||||
|
isWorkspaceEventsEnabled() {
|
||||||
|
return this._eventsEnabled;
|
||||||
|
},
|
||||||
|
|
||||||
|
dumpNativeChart() {
|
||||||
|
return this._workspace.dumpNativeChart();
|
||||||
|
},
|
||||||
|
|
||||||
|
_registerDragEvents() {
|
||||||
|
const workspace = this._workspace;
|
||||||
|
const screenManager = this._screenManager;
|
||||||
|
const mWorkspace = this;
|
||||||
|
const mouseDownListener = function (event) {
|
||||||
|
if (!$defined(workspace._mouseMoveListener)) {
|
||||||
|
if (mWorkspace.isWorkspaceEventsEnabled()) {
|
||||||
|
mWorkspace.enableWorkspaceEvents(false);
|
||||||
|
|
||||||
|
const mouseDownPosition = screenManager.getWorkspaceMousePosition(event);
|
||||||
|
const originalCoordOrigin = workspace.getCoordOrigin();
|
||||||
|
|
||||||
|
let wasDragged = false;
|
||||||
|
workspace._mouseMoveListener = function (event) {
|
||||||
|
const currentMousePosition = screenManager.getWorkspaceMousePosition(event);
|
||||||
|
|
||||||
|
const offsetX = currentMousePosition.x - mouseDownPosition.x;
|
||||||
|
const coordOriginX = -offsetX + originalCoordOrigin.x;
|
||||||
|
|
||||||
|
const offsetY = currentMousePosition.y - mouseDownPosition.y;
|
||||||
|
const coordOriginY = -offsetY + originalCoordOrigin.y;
|
||||||
|
|
||||||
|
workspace.setCoordOrigin(coordOriginX, coordOriginY);
|
||||||
|
|
||||||
|
// Change cursor.
|
||||||
|
if (Browser.firefox) {
|
||||||
|
window.document.body.style.cursor = '-moz-grabbing';
|
||||||
|
} else {
|
||||||
|
window.document.body.style.cursor = 'move';
|
||||||
|
}
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
// Fire drag event ...
|
||||||
|
screenManager.fireEvent('update');
|
||||||
|
wasDragged = true;
|
||||||
|
};
|
||||||
|
screenManager.addEvent('mousemove', workspace._mouseMoveListener);
|
||||||
|
|
||||||
|
// Register mouse up listeners ...
|
||||||
|
workspace._mouseUpListener = function (event) {
|
||||||
|
screenManager.removeEvent('mousemove', workspace._mouseMoveListener);
|
||||||
|
screenManager.removeEvent('mouseup', workspace._mouseUpListener);
|
||||||
|
workspace._mouseUpListener = null;
|
||||||
|
workspace._mouseMoveListener = null;
|
||||||
|
window.document.body.style.cursor = 'default';
|
||||||
|
|
||||||
|
// Update screen manager offset.
|
||||||
|
const coordOrigin = workspace.getCoordOrigin();
|
||||||
|
screenManager.setOffset(coordOrigin.x, coordOrigin.y);
|
||||||
|
mWorkspace.enableWorkspaceEvents(true);
|
||||||
|
|
||||||
|
if (!wasDragged) {
|
||||||
|
screenManager.fireEvent('click');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
screenManager.addEvent('mouseup', workspace._mouseUpListener);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
workspace._mouseUpListener();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
screenManager.addEvent('mousedown', mouseDownListener);
|
||||||
|
},
|
||||||
|
|
||||||
|
setViewPort(size) {
|
||||||
|
this._viewPort = size;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default Workspace;
|
export default Workspace;
|
||||||
|
@ -18,8 +18,8 @@
|
|||||||
const Command = require('../Command').default;
|
const Command = require('../Command').default;
|
||||||
|
|
||||||
const AddFeatureToTopicCommand = new Class(/** @lends AddFeatureToTopicCommand */{
|
const AddFeatureToTopicCommand = new Class(/** @lends AddFeatureToTopicCommand */{
|
||||||
Extends: Command,
|
Extends: Command,
|
||||||
/**
|
/**
|
||||||
* @classdesc This command class handles do/undo of adding features to topics, e.g. an
|
* @classdesc This command class handles do/undo of adding features to topics, e.g. an
|
||||||
* icon or a note. For a reference of existing features, refer to {@link mindplot.TopicFeature}
|
* icon or a note. For a reference of existing features, refer to {@link mindplot.TopicFeature}
|
||||||
* @constructs
|
* @constructs
|
||||||
@ -29,41 +29,40 @@ const AddFeatureToTopicCommand = new Class(/** @lends AddFeatureToTopicCommand *
|
|||||||
* @extends mindplot.Command
|
* @extends mindplot.Command
|
||||||
* @see mindplot.model.FeatureModel and subclasses
|
* @see mindplot.model.FeatureModel and subclasses
|
||||||
*/
|
*/
|
||||||
initialize:function (topicId, featureType, attributes) {
|
initialize(topicId, featureType, attributes) {
|
||||||
|
$assert($defined(topicId), 'topicId can not be null');
|
||||||
|
$assert(featureType, 'featureType can not be null');
|
||||||
|
$assert(attributes, 'attributes can not be null');
|
||||||
|
|
||||||
$assert($defined(topicId), 'topicId can not be null');
|
this.parent();
|
||||||
$assert(featureType, 'featureType can not be null');
|
this._topicId = topicId;
|
||||||
$assert(attributes, 'attributes can not be null');
|
this._featureType = featureType;
|
||||||
|
this._attributes = attributes;
|
||||||
|
this._featureModel = null;
|
||||||
|
},
|
||||||
|
|
||||||
this.parent();
|
/**
|
||||||
this._topicId = topicId;
|
|
||||||
this._featureType = featureType;
|
|
||||||
this._attributes = attributes;
|
|
||||||
this._featureModel = null;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Overrides abstract parent method
|
* Overrides abstract parent method
|
||||||
*/
|
*/
|
||||||
execute:function (commandContext) {
|
execute(commandContext) {
|
||||||
var topic = commandContext.findTopics(this._topicId)[0];
|
const topic = commandContext.findTopics(this._topicId)[0];
|
||||||
|
|
||||||
// Feature must be created only one time.
|
// Feature must be created only one time.
|
||||||
if (!this._featureModel) {
|
if (!this._featureModel) {
|
||||||
var model = topic.getModel();
|
const model = topic.getModel();
|
||||||
this._featureModel = model.createFeature(this._featureType, this._attributes);
|
this._featureModel = model.createFeature(this._featureType, this._attributes);
|
||||||
}
|
}
|
||||||
topic.addFeature(this._featureModel);
|
topic.addFeature(this._featureModel);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides abstract parent method
|
* Overrides abstract parent method
|
||||||
* @see {@link mindplot.Command.undoExecute}
|
* @see {@link mindplot.Command.undoExecute}
|
||||||
*/
|
*/
|
||||||
undoExecute:function (commandContext) {
|
undoExecute(commandContext) {
|
||||||
var topic = commandContext.findTopics(this._topicId)[0];
|
const topic = commandContext.findTopics(this._topicId)[0];
|
||||||
topic.removeFeature(this._featureModel);
|
topic.removeFeature(this._featureModel);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default AddFeatureToTopicCommand
|
export default AddFeatureToTopicCommand;
|
||||||
|
@ -15,39 +15,39 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
const Command = require('../Command').default
|
const Command = require('../Command').default;
|
||||||
|
|
||||||
const AddRelationshipCommand = new Class(/** @lends AddRelationshipCommand */{
|
const AddRelationshipCommand = new Class(/** @lends AddRelationshipCommand */{
|
||||||
Extends:Command,
|
Extends: Command,
|
||||||
/**
|
/**
|
||||||
* @classdesc This command class handles do/undo of adding a relationship to a topic.
|
* @classdesc This command class handles do/undo of adding a relationship to a topic.
|
||||||
* @constructs
|
* @constructs
|
||||||
* @param {XMLDOM} model
|
* @param {XMLDOM} model
|
||||||
* @extends mindplot.Command
|
* @extends mindplot.Command
|
||||||
*/
|
*/
|
||||||
initialize:function (model) {
|
initialize(model) {
|
||||||
$assert(model, 'Relationship model can not be null');
|
$assert(model, 'Relationship model can not be null');
|
||||||
|
|
||||||
this.parent();
|
this.parent();
|
||||||
this._model = model;
|
this._model = model;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides abstract parent method
|
* Overrides abstract parent method
|
||||||
*/
|
*/
|
||||||
execute:function (commandContext) {
|
execute(commandContext) {
|
||||||
var relationship = commandContext.addRelationship(this._model);
|
const relationship = commandContext.addRelationship(this._model);
|
||||||
relationship.setOnFocus(true);
|
relationship.setOnFocus(true);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides abstract parent method
|
* Overrides abstract parent method
|
||||||
* @see {@link mindplot.Command.undoExecute}
|
* @see {@link mindplot.Command.undoExecute}
|
||||||
*/
|
*/
|
||||||
undoExecute:function (commandContext) {
|
undoExecute(commandContext) {
|
||||||
var rel = commandContext.findRelationships(this._model.getId());
|
const rel = commandContext.findRelationships(this._model.getId());
|
||||||
commandContext.deleteRelationship(rel[0]);
|
commandContext.deleteRelationship(rel[0]);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default AddRelationshipCommand;
|
export default AddRelationshipCommand;
|
||||||
|
@ -18,9 +18,9 @@
|
|||||||
const Command = require('../Command').default;
|
const Command = require('../Command').default;
|
||||||
|
|
||||||
const AddTopicCommand = new Class(
|
const AddTopicCommand = new Class(
|
||||||
/** @lends AddTopicCommand */ {
|
/** @lends AddTopicCommand */ {
|
||||||
Extends: Command,
|
Extends: Command,
|
||||||
/**
|
/**
|
||||||
* @classdesc This command class handles do/undo of adding one or multiple topics to
|
* @classdesc This command class handles do/undo of adding one or multiple topics to
|
||||||
* the mindmap.
|
* the mindmap.
|
||||||
* @constructs
|
* @constructs
|
||||||
@ -29,69 +29,69 @@ const AddTopicCommand = new Class(
|
|||||||
* when attaching a dragged node or a node/branch from clipboard
|
* when attaching a dragged node or a node/branch from clipboard
|
||||||
* @extends mindplot.Command
|
* @extends mindplot.Command
|
||||||
*/
|
*/
|
||||||
initialize: function (models, parentTopicsId) {
|
initialize(models, parentTopicsId) {
|
||||||
$assert(models, 'models can not be null');
|
$assert(models, 'models can not be null');
|
||||||
$assert(
|
$assert(
|
||||||
parentTopicsId == null || parentTopicsId.length == models.length,
|
parentTopicsId == null || parentTopicsId.length == models.length,
|
||||||
'parents and models must have the same size'
|
'parents and models must have the same size',
|
||||||
);
|
);
|
||||||
|
|
||||||
this.parent();
|
this.parent();
|
||||||
this._models = models;
|
this._models = models;
|
||||||
this._parentsIds = parentTopicsId;
|
this._parentsIds = parentTopicsId;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides abstract parent method
|
* Overrides abstract parent method
|
||||||
*/
|
*/
|
||||||
execute: function (commandContext) {
|
execute(commandContext) {
|
||||||
var me = this;
|
const me = this;
|
||||||
_.each(this._models, function (model, index) {
|
_.each(this._models, (model, index) => {
|
||||||
// Add a new topic ...
|
// Add a new topic ...
|
||||||
var topic = commandContext.createTopic(model);
|
const topic = commandContext.createTopic(model);
|
||||||
|
|
||||||
// Connect to topic ...
|
// Connect to topic ...
|
||||||
if (me._parentsIds) {
|
if (me._parentsIds) {
|
||||||
var parentId = me._parentsIds[index];
|
const parentId = me._parentsIds[index];
|
||||||
if ($defined(parentId)) {
|
if ($defined(parentId)) {
|
||||||
var parentTopic = commandContext.findTopics(parentId)[0];
|
const parentTopic = commandContext.findTopics(parentId)[0];
|
||||||
commandContext.connect(topic, parentTopic);
|
commandContext.connect(topic, parentTopic);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
commandContext.addTopic(topic);
|
commandContext.addTopic(topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select just created node ...
|
// Select just created node ...
|
||||||
var designer = commandContext._designer;
|
const designer = commandContext._designer;
|
||||||
designer.onObjectFocusEvent(topic);
|
designer.onObjectFocusEvent(topic);
|
||||||
topic.setOnFocus(true);
|
topic.setOnFocus(true);
|
||||||
|
|
||||||
// Render node ...
|
// Render node ...
|
||||||
topic.setVisibility(true);
|
topic.setVisibility(true);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides abstract parent method
|
* Overrides abstract parent method
|
||||||
* @see {@link mindplot.Command.undoExecute}
|
* @see {@link mindplot.Command.undoExecute}
|
||||||
*/
|
*/
|
||||||
undoExecute: function (commandContext) {
|
undoExecute(commandContext) {
|
||||||
// Delete disconnected the nodes. Create a copy of the topics ...
|
// Delete disconnected the nodes. Create a copy of the topics ...
|
||||||
var clonedModel = [];
|
const clonedModel = [];
|
||||||
_.each(this._models, function (model) {
|
_.each(this._models, (model) => {
|
||||||
clonedModel.push(model.clone());
|
clonedModel.push(model.clone());
|
||||||
});
|
});
|
||||||
|
|
||||||
// Finally, remove the nodes ...
|
// Finally, remove the nodes ...
|
||||||
_.each(this._models, function (model) {
|
_.each(this._models, (model) => {
|
||||||
var topicId = model.getId();
|
const topicId = model.getId();
|
||||||
var topic = commandContext.findTopics(topicId)[0];
|
const topic = commandContext.findTopics(topicId)[0];
|
||||||
commandContext.deleteTopic(topic);
|
commandContext.deleteTopic(topic);
|
||||||
});
|
});
|
||||||
|
|
||||||
this._models = clonedModel;
|
this._models = clonedModel;
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
export default AddTopicCommand;
|
export default AddTopicCommand;
|
||||||
|
@ -15,11 +15,11 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
const Command = require('../Command').default
|
const Command = require('../Command').default;
|
||||||
|
|
||||||
const ChangeFeatureToTopicCommand = new Class(/** @lends ChangeFeatureToTopicCommand */{
|
const ChangeFeatureToTopicCommand = new Class(/** @lends ChangeFeatureToTopicCommand */{
|
||||||
Extends:Command,
|
Extends: Command,
|
||||||
/**
|
/**
|
||||||
* @extends mindplot.Command
|
* @extends mindplot.Command
|
||||||
* @constructs
|
* @constructs
|
||||||
* @param topicId
|
* @param topicId
|
||||||
@ -29,36 +29,36 @@ const ChangeFeatureToTopicCommand = new Class(/** @lends ChangeFeatureToTopicCom
|
|||||||
* @throws will throw an error if featureId is null or undefined
|
* @throws will throw an error if featureId is null or undefined
|
||||||
* @throws will throw an error if attributes is null or undefined
|
* @throws will throw an error if attributes is null or undefined
|
||||||
*/
|
*/
|
||||||
initialize: function(topicId, featureId, attributes) {
|
initialize(topicId, featureId, attributes) {
|
||||||
$assert($defined(topicId), 'topicId can not be null');
|
$assert($defined(topicId), 'topicId can not be null');
|
||||||
$assert($defined(featureId), 'featureId can not be null');
|
$assert($defined(featureId), 'featureId can not be null');
|
||||||
$assert($defined(attributes), 'attributes can not be null');
|
$assert($defined(attributes), 'attributes can not be null');
|
||||||
|
|
||||||
this.parent();
|
this.parent();
|
||||||
this._topicId = topicId;
|
this._topicId = topicId;
|
||||||
this._featureId = featureId;
|
this._featureId = featureId;
|
||||||
this._attributes = attributes;
|
this._attributes = attributes;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides abstract parent method
|
* Overrides abstract parent method
|
||||||
*/
|
*/
|
||||||
execute: function(commandContext) {
|
execute(commandContext) {
|
||||||
var topic = commandContext.findTopics(this._topicId)[0];
|
const topic = commandContext.findTopics(this._topicId)[0];
|
||||||
var feature = topic.findFeatureById(this._featureId);
|
const feature = topic.findFeatureById(this._featureId);
|
||||||
|
|
||||||
var oldAttributes = feature.getAttributes();
|
const oldAttributes = feature.getAttributes();
|
||||||
feature.setAttributes(this._attributes);
|
feature.setAttributes(this._attributes);
|
||||||
this._attributes = oldAttributes;
|
this._attributes = oldAttributes;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides abstract parent method
|
* Overrides abstract parent method
|
||||||
* @see {@link mindplot.Command.undoExecute}
|
* @see {@link mindplot.Command.undoExecute}
|
||||||
*/
|
*/
|
||||||
undoExecute: function(commandContext) {
|
undoExecute(commandContext) {
|
||||||
this.execute(commandContext);
|
this.execute(commandContext);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default ChangeFeatureToTopicCommand;
|
export default ChangeFeatureToTopicCommand;
|
||||||
|
@ -18,169 +18,162 @@
|
|||||||
const Command = require('../Command').default;
|
const Command = require('../Command').default;
|
||||||
|
|
||||||
const DeleteCommand = new Class(/** @lends mindplot.commands.DeleteCommand */{
|
const DeleteCommand = new Class(/** @lends mindplot.commands.DeleteCommand */{
|
||||||
Extends:Command,
|
Extends: Command,
|
||||||
/**
|
/**
|
||||||
* @classdesc This command class handles do/undo of deleting a topic.
|
* @classdesc This command class handles do/undo of deleting a topic.
|
||||||
* @constructs
|
* @constructs
|
||||||
* @param {Array<String>} topicIds ids of the topics to delete
|
* @param {Array<String>} topicIds ids of the topics to delete
|
||||||
* @param {Array<String>} relIds ids of the relationships connected to the topics
|
* @param {Array<String>} relIds ids of the relationships connected to the topics
|
||||||
* @extends mindplot.Command
|
* @extends mindplot.Command
|
||||||
*/
|
*/
|
||||||
initialize:function (topicIds, relIds) {
|
initialize(topicIds, relIds) {
|
||||||
$assert($defined(relIds), 'topicIds can not be null');
|
$assert($defined(relIds), 'topicIds can not be null');
|
||||||
|
|
||||||
this.parent();
|
this.parent();
|
||||||
this._relIds = relIds;
|
this._relIds = relIds;
|
||||||
this._topicIds = topicIds;
|
this._topicIds = topicIds;
|
||||||
this._deletedTopicModels = [];
|
this._deletedTopicModels = [];
|
||||||
this._deletedRelModel = [];
|
this._deletedRelModel = [];
|
||||||
this._parentTopicIds = [];
|
this._parentTopicIds = [];
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides abstract parent method
|
* Overrides abstract parent method
|
||||||
*/
|
*/
|
||||||
execute:function (commandContext) {
|
execute(commandContext) {
|
||||||
|
// If a parent has been selected for deletion, the children must be excluded from the delete ...
|
||||||
|
const topics = this._filterChildren(this._topicIds, commandContext);
|
||||||
|
|
||||||
// If a parent has been selected for deletion, the children must be excluded from the delete ...
|
if (topics.length > 0) {
|
||||||
var topics = this._filterChildren(this._topicIds, commandContext);
|
_.each(topics, function (topic) {
|
||||||
|
// In case that it's editing text node, force close without update ...
|
||||||
|
topic.closeEditors();
|
||||||
|
|
||||||
if (topics.length > 0) {
|
const model = topic.getModel();
|
||||||
_.each(topics, function (topic) {
|
|
||||||
// In case that it's editing text node, force close without update ...
|
|
||||||
topic.closeEditors();
|
|
||||||
|
|
||||||
var model = topic.getModel();
|
// Delete relationships
|
||||||
|
const relationships = this._collectInDepthRelationships(topic);
|
||||||
|
this._deletedRelModel.append(relationships.map((rel) => rel.getModel().clone()));
|
||||||
|
|
||||||
// Delete relationships
|
_.each(relationships, (relationship) => {
|
||||||
var relationships = this._collectInDepthRelationships(topic);
|
commandContext.deleteRelationship(relationship);
|
||||||
this._deletedRelModel.append(relationships.map(function (rel) {
|
});
|
||||||
return rel.getModel().clone();
|
|
||||||
}));
|
|
||||||
|
|
||||||
_.each(relationships, function (relationship) {
|
// Store information for undo ...
|
||||||
commandContext.deleteRelationship(relationship);
|
const clonedModel = model.clone();
|
||||||
});
|
this._deletedTopicModels.push(clonedModel);
|
||||||
|
const outTopic = topic.getOutgoingConnectedTopic();
|
||||||
// Store information for undo ...
|
let outTopicId = null;
|
||||||
var clonedModel = model.clone();
|
if (outTopic != null) {
|
||||||
this._deletedTopicModels.push(clonedModel);
|
outTopicId = outTopic.getId();
|
||||||
var outTopic = topic.getOutgoingConnectedTopic();
|
|
||||||
var outTopicId = null;
|
|
||||||
if (outTopic != null) {
|
|
||||||
outTopicId = outTopic.getId();
|
|
||||||
}
|
|
||||||
this._parentTopicIds.push(outTopicId);
|
|
||||||
|
|
||||||
// Finally, delete the topic from the workspace...
|
|
||||||
commandContext.deleteTopic(topic);
|
|
||||||
|
|
||||||
}, this);
|
|
||||||
}
|
}
|
||||||
|
this._parentTopicIds.push(outTopicId);
|
||||||
|
|
||||||
var rels = commandContext.findRelationships(this._relIds);
|
// Finally, delete the topic from the workspace...
|
||||||
if (rels.length > 0) {
|
commandContext.deleteTopic(topic);
|
||||||
_.each(rels, function (rel) {
|
}, this);
|
||||||
this._deletedRelModel.push(rel.getModel().clone());
|
}
|
||||||
commandContext.deleteRelationship(rel);
|
|
||||||
}, this);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
const rels = commandContext.findRelationships(this._relIds);
|
||||||
|
if (rels.length > 0) {
|
||||||
|
_.each(rels, function (rel) {
|
||||||
|
this._deletedRelModel.push(rel.getModel().clone());
|
||||||
|
commandContext.deleteRelationship(rel);
|
||||||
|
}, this);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
* Overrides abstract parent method
|
* Overrides abstract parent method
|
||||||
* @see {@link mindplot.Command.undoExecute}
|
* @see {@link mindplot.Command.undoExecute}
|
||||||
*/
|
*/
|
||||||
undoExecute:function (commandContext) {
|
undoExecute(commandContext) {
|
||||||
|
// Add all the topics ...
|
||||||
|
_.each(this._deletedTopicModels, (model) => {
|
||||||
|
commandContext.createTopic(model);
|
||||||
|
}, this);
|
||||||
|
|
||||||
// Add all the topics ...
|
// Do they need to be connected ?
|
||||||
_.each(this._deletedTopicModels, function (model) {
|
_.each(this._deletedTopicModels, function (topicModel, index) {
|
||||||
commandContext.createTopic(model);
|
const topics = commandContext.findTopics(topicModel.getId());
|
||||||
}, this);
|
|
||||||
|
|
||||||
// Do they need to be connected ?
|
const parentId = this._parentTopicIds[index];
|
||||||
_.each(this._deletedTopicModels, function (topicModel, index) {
|
if (parentId) {
|
||||||
var topics = commandContext.findTopics(topicModel.getId());
|
const parentTopics = commandContext.findTopics(parentId);
|
||||||
|
commandContext.connect(topics[0], parentTopics[0]);
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
|
||||||
var parentId = this._parentTopicIds[index];
|
// Add rebuild relationships ...
|
||||||
if (parentId) {
|
_.each(this._deletedRelModel, (model) => {
|
||||||
var parentTopics = commandContext.findTopics(parentId);
|
commandContext.addRelationship(model);
|
||||||
commandContext.connect(topics[0], parentTopics[0]);
|
});
|
||||||
}
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
// Add rebuild relationships ...
|
// Finally display the topics ...
|
||||||
_.each(this._deletedRelModel, function (model) {
|
_.each(this._deletedTopicModels, (topicModel) => {
|
||||||
commandContext.addRelationship(model);
|
const topics = commandContext.findTopics(topicModel.getId());
|
||||||
});
|
topics[0].setBranchVisibility(true);
|
||||||
|
}, this);
|
||||||
|
|
||||||
// Finally display the topics ...
|
// Focus on last recovered topic ..
|
||||||
_.each(this._deletedTopicModels, function (topicModel) {
|
if (this._deletedTopicModels.length > 0) {
|
||||||
var topics = commandContext.findTopics(topicModel.getId());
|
const firstTopic = this._deletedTopicModels[0];
|
||||||
topics[0].setBranchVisibility(true);
|
const topic = commandContext.findTopics(firstTopic.getId())[0];
|
||||||
}, this);
|
topic.setOnFocus(true);
|
||||||
|
|
||||||
// Focus on last recovered topic ..
|
|
||||||
if (this._deletedTopicModels.length > 0) {
|
|
||||||
var firstTopic = this._deletedTopicModels[0];
|
|
||||||
var topic = commandContext.findTopics(firstTopic.getId())[0];
|
|
||||||
topic.setOnFocus(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._deletedTopicModels = [];
|
|
||||||
this._parentTopicIds = [];
|
|
||||||
this._deletedRelModel = [];
|
|
||||||
},
|
|
||||||
|
|
||||||
_filterChildren:function (topicIds, commandContext) {
|
|
||||||
var topics = commandContext.findTopics(topicIds);
|
|
||||||
|
|
||||||
var result = [];
|
|
||||||
_.each(topics, function (topic) {
|
|
||||||
var parent = topic.getParent();
|
|
||||||
var found = false;
|
|
||||||
while (parent != null && !found) {
|
|
||||||
found = topicIds.contains(parent.getId());
|
|
||||||
if (found) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
parent = parent.getParent();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found) {
|
|
||||||
result.push(topic);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
_collectInDepthRelationships:function (topic) {
|
|
||||||
var result = [];
|
|
||||||
result.append(topic.getRelationships());
|
|
||||||
|
|
||||||
var children = topic.getChildren();
|
|
||||||
var rels = children.map(function (topic) {
|
|
||||||
return this._collectInDepthRelationships(topic);
|
|
||||||
}, this);
|
|
||||||
result.append(rels.flatten());
|
|
||||||
|
|
||||||
if (result.length > 0) {
|
|
||||||
// Filter for unique ...
|
|
||||||
result = result.sort(function (a, b) {
|
|
||||||
return a.getModel().getId() - b.getModel().getId();
|
|
||||||
});
|
|
||||||
var ret = [result[0]];
|
|
||||||
for (var i = 1; i < result.length; i++) { // start loop at 1 as element 0 can never be a duplicate
|
|
||||||
if (result[i - 1] !== result[i]) {
|
|
||||||
ret.push(result[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result = ret;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._deletedTopicModels = [];
|
||||||
|
this._parentTopicIds = [];
|
||||||
|
this._deletedRelModel = [];
|
||||||
|
},
|
||||||
|
|
||||||
|
_filterChildren(topicIds, commandContext) {
|
||||||
|
const topics = commandContext.findTopics(topicIds);
|
||||||
|
|
||||||
|
const result = [];
|
||||||
|
_.each(topics, (topic) => {
|
||||||
|
let parent = topic.getParent();
|
||||||
|
let found = false;
|
||||||
|
while (parent != null && !found) {
|
||||||
|
found = topicIds.contains(parent.getId());
|
||||||
|
if (found) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
parent = parent.getParent();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
result.push(topic);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
_collectInDepthRelationships(topic) {
|
||||||
|
let result = [];
|
||||||
|
result.append(topic.getRelationships());
|
||||||
|
|
||||||
|
const children = topic.getChildren();
|
||||||
|
const rels = children.map(function (topic) {
|
||||||
|
return this._collectInDepthRelationships(topic);
|
||||||
|
}, this);
|
||||||
|
result.append(rels.flatten());
|
||||||
|
|
||||||
|
if (result.length > 0) {
|
||||||
|
// Filter for unique ...
|
||||||
|
result = result.sort((a, b) => a.getModel().getId() - b.getModel().getId());
|
||||||
|
const ret = [result[0]];
|
||||||
|
for (let i = 1; i < result.length; i++) { // start loop at 1 as element 0 can never be a duplicate
|
||||||
|
if (result[i - 1] !== result[i]) {
|
||||||
|
ret.push(result[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = ret;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default DeleteCommand;
|
export default DeleteCommand;
|
||||||
|
@ -15,11 +15,11 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
const Command = require('../Command').default
|
const Command = require('../Command').default;
|
||||||
|
|
||||||
const DragTopicCommand = new Class(/** @lends DragTopicCommand */{
|
const DragTopicCommand = new Class(/** @lends DragTopicCommand */{
|
||||||
Extends:Command,
|
Extends: Command,
|
||||||
/**
|
/**
|
||||||
* @classdesc This command class handles do/undo of dragging a topic to a new position.
|
* @classdesc This command class handles do/undo of dragging a topic to a new position.
|
||||||
* @constructs
|
* @constructs
|
||||||
* @param {String} topicId id of the topic to drag
|
* @param {String} topicId id of the topic to drag
|
||||||
@ -28,76 +28,72 @@ const DragTopicCommand = new Class(/** @lends DragTopicCommand */{
|
|||||||
* @param {mindplot.Topic} parentTopic the topic to be made the dragged topic's new parent
|
* @param {mindplot.Topic} parentTopic the topic to be made the dragged topic's new parent
|
||||||
* @extends mindplot.Command
|
* @extends mindplot.Command
|
||||||
*/
|
*/
|
||||||
initialize:function (topicId, position, order, parentTopic) {
|
initialize(topicId, position, order, parentTopic) {
|
||||||
$assert(topicId, "topicId must be defined");
|
$assert(topicId, 'topicId must be defined');
|
||||||
|
|
||||||
this._topicsId = topicId;
|
this._topicsId = topicId;
|
||||||
if ($defined(parentTopic))
|
if ($defined(parentTopic)) this._parentId = parentTopic.getId();
|
||||||
this._parentId = parentTopic.getId();
|
|
||||||
|
|
||||||
this.parent();
|
this.parent();
|
||||||
this._position = position;
|
this._position = position;
|
||||||
this._order = order;
|
this._order = order;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides abstract parent method
|
* Overrides abstract parent method
|
||||||
*/
|
*/
|
||||||
execute:function (commandContext) {
|
execute(commandContext) {
|
||||||
|
const topic = commandContext.findTopics(this._topicsId)[0];
|
||||||
|
topic.setVisibility(false);
|
||||||
|
|
||||||
var topic = commandContext.findTopics(this._topicsId)[0];
|
// Save old position ...
|
||||||
topic.setVisibility(false);
|
const origParentTopic = topic.getOutgoingConnectedTopic();
|
||||||
|
|
||||||
// Save old position ...
|
// In this case, topics are positioned using order ...
|
||||||
var origParentTopic = topic.getOutgoingConnectedTopic();
|
const origOrder = topic.getOrder();
|
||||||
|
const origPosition = topic.getPosition();
|
||||||
|
|
||||||
// In this case, topics are positioned using order ...
|
// Disconnect topic ..
|
||||||
var origOrder = topic.getOrder();
|
if ($defined(origParentTopic) && origParentTopic != this._parentId) {
|
||||||
var origPosition = topic.getPosition();
|
commandContext.disconnect(topic);
|
||||||
|
}
|
||||||
|
|
||||||
// Disconnect topic ..
|
// Set topic order ...
|
||||||
if ($defined(origParentTopic) && origParentTopic != this._parentId) {
|
if (this._order != null) {
|
||||||
commandContext.disconnect(topic);
|
topic.setOrder(this._order);
|
||||||
}
|
} else if (this._position != null) {
|
||||||
|
commandContext.moveTopic(topic, this._position);
|
||||||
|
} else {
|
||||||
|
$assert('Illegal command state exception.');
|
||||||
|
}
|
||||||
|
|
||||||
// Set topic order ...
|
// Finally, connect topic ...
|
||||||
if (this._order != null) {
|
if (origParentTopic != this._parentId) {
|
||||||
topic.setOrder(this._order);
|
if ($defined(this._parentId)) {
|
||||||
} else if (this._position != null) {
|
const parentTopic = commandContext.findTopics(this._parentId)[0];
|
||||||
commandContext.moveTopic(topic, this._position);
|
commandContext.connect(topic, parentTopic);
|
||||||
} else {
|
}
|
||||||
$assert("Illegal command state exception.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally, connect topic ...
|
// Backup old parent id ...
|
||||||
if (origParentTopic != this._parentId) {
|
this._parentId = null;
|
||||||
|
if ($defined(origParentTopic)) {
|
||||||
|
this._parentId = origParentTopic.getId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
topic.setVisibility(true);
|
||||||
|
|
||||||
if ($defined(this._parentId)) {
|
// Store for undo ...
|
||||||
var parentTopic = commandContext.findTopics(this._parentId)[0];
|
this._order = origOrder;
|
||||||
commandContext.connect(topic, parentTopic);
|
this._position = origPosition;
|
||||||
}
|
},
|
||||||
|
|
||||||
// Backup old parent id ...
|
/**
|
||||||
this._parentId = null;
|
|
||||||
if ($defined(origParentTopic)) {
|
|
||||||
this._parentId = origParentTopic.getId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
topic.setVisibility(true);
|
|
||||||
|
|
||||||
// Store for undo ...
|
|
||||||
this._order = origOrder;
|
|
||||||
this._position = origPosition;
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Overrides abstract parent method
|
* Overrides abstract parent method
|
||||||
* @see {@link mindplot.Command.undoExecute}
|
* @see {@link mindplot.Command.undoExecute}
|
||||||
*/
|
*/
|
||||||
undoExecute:function (commandContext) {
|
undoExecute(commandContext) {
|
||||||
this.execute(commandContext);
|
this.execute(commandContext);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default DragTopicCommand;
|
export default DragTopicCommand;
|
||||||
|
@ -15,11 +15,11 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
const Command = require('../Command').default
|
const Command = require('../Command').default;
|
||||||
|
|
||||||
const GenericFunctionCommand = new Class(/** @lends GenericFunctionCommand */{
|
const GenericFunctionCommand = new Class(/** @lends GenericFunctionCommand */{
|
||||||
Extends:Command,
|
Extends: Command,
|
||||||
/**
|
/**
|
||||||
* @classdesc This command handles do/undo of different actions, e.g. moving topics to
|
* @classdesc This command handles do/undo of different actions, e.g. moving topics to
|
||||||
* a different position, changing text or font,... (for full reference check the
|
* a different position, changing text or font,... (for full reference check the
|
||||||
* StandaloneActionDispatcher i.e. the ActionDispatcher subclass in use)
|
* StandaloneActionDispatcher i.e. the ActionDispatcher subclass in use)
|
||||||
@ -30,70 +30,66 @@ const GenericFunctionCommand = new Class(/** @lends GenericFunctionCommand */{
|
|||||||
* e.g. color, font family or text
|
* e.g. color, font family or text
|
||||||
* @extends mindplot.Command
|
* @extends mindplot.Command
|
||||||
*/
|
*/
|
||||||
initialize:function (commandFunc, topicsIds, value) {
|
initialize(commandFunc, topicsIds, value) {
|
||||||
$assert(commandFunc, "commandFunc must be defined");
|
$assert(commandFunc, 'commandFunc must be defined');
|
||||||
$assert($defined(topicsIds), "topicsIds must be defined");
|
$assert($defined(topicsIds), 'topicsIds must be defined');
|
||||||
|
|
||||||
this.parent();
|
this.parent();
|
||||||
this._value = value;
|
this._value = value;
|
||||||
this._topicsId = topicsIds;
|
this._topicsId = topicsIds;
|
||||||
this._commandFunc = commandFunc;
|
this._commandFunc = commandFunc;
|
||||||
this._oldValues = [];
|
this._oldValues = [];
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides abstract parent method
|
* Overrides abstract parent method
|
||||||
*/
|
*/
|
||||||
execute:function (commandContext) {
|
execute(commandContext) {
|
||||||
if (!this.applied) {
|
if (!this.applied) {
|
||||||
|
let topics = null;
|
||||||
var topics = null;
|
try {
|
||||||
try {
|
topics = commandContext.findTopics(this._topicsId);
|
||||||
topics = commandContext.findTopics(this._topicsId);
|
} catch (e) {
|
||||||
} catch (e) {
|
if (this._commandFunc.commandType != 'changeTextToTopic') {
|
||||||
if (this._commandFunc.commandType != "changeTextToTopic") {
|
// Workaround: For some reason, there is a combination of events that involves
|
||||||
// Workaround: For some reason, there is a combination of events that involves
|
// making some modification and firing out of focus event. This is causing
|
||||||
// making some modification and firing out of focus event. This is causing
|
// that a remove node try to be removed. In some other life, I will come with the solution.
|
||||||
// that a remove node try to be removed. In some other life, I will come with the solution.
|
// Almost aways occurs with IE9. I could be related with some change of order in sets o something similar.
|
||||||
// Almost aways occurs with IE9. I could be related with some change of order in sets o something similar.
|
throw e;
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (topics != null) {
|
|
||||||
var me = this;
|
|
||||||
_.each(topics, function (topic) {
|
|
||||||
var oldValue = me._commandFunc(topic, me._value);
|
|
||||||
me._oldValues.push(oldValue);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.applied = true;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
throw "Command can not be applied two times in a row.";
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
},
|
if (topics != null) {
|
||||||
|
const me = this;
|
||||||
|
_.each(topics, (topic) => {
|
||||||
|
const oldValue = me._commandFunc(topic, me._value);
|
||||||
|
me._oldValues.push(oldValue);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.applied = true;
|
||||||
|
} else {
|
||||||
|
throw 'Command can not be applied two times in a row.';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides abstract parent method
|
* Overrides abstract parent method
|
||||||
* @see {@link mindplot.Command.undoExecute}
|
* @see {@link mindplot.Command.undoExecute}
|
||||||
*/
|
*/
|
||||||
undoExecute:function (commandContext) {
|
undoExecute(commandContext) {
|
||||||
if (this.applied) {
|
if (this.applied) {
|
||||||
var topics = commandContext.findTopics(this._topicsId);
|
const topics = commandContext.findTopics(this._topicsId);
|
||||||
var me = this;
|
const me = this;
|
||||||
_.each(topics, function (topic, index) {
|
_.each(topics, (topic, index) => {
|
||||||
me._commandFunc(topic, me._oldValues[index]);
|
me._commandFunc(topic, me._oldValues[index]);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
this.applied = false;
|
||||||
|
this._oldValues = [];
|
||||||
this.applied = false;
|
} else {
|
||||||
this._oldValues = [];
|
throw 'undo can not be applied.';
|
||||||
} else {
|
|
||||||
throw "undo can not be applied.";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default GenericFunctionCommand
|
export default GenericFunctionCommand;
|
||||||
|
@ -18,9 +18,9 @@
|
|||||||
const Command = require('../Command').default;
|
const Command = require('../Command').default;
|
||||||
|
|
||||||
const MoveControlPointCommand = new Class(
|
const MoveControlPointCommand = new Class(
|
||||||
/** @lends MoveControlPointCommand */ {
|
/** @lends MoveControlPointCommand */ {
|
||||||
Extends: Command,
|
Extends: Command,
|
||||||
/**
|
/**
|
||||||
* @classdesc This command handles do/undo of changing the control points of a relationship
|
* @classdesc This command handles do/undo of changing the control points of a relationship
|
||||||
* arrow. These are the two points that appear when the relationship is on focus. They
|
* arrow. These are the two points that appear when the relationship is on focus. They
|
||||||
* influence how the arrow is drawn (not the source or the destination topic nor the arrow
|
* influence how the arrow is drawn (not the source or the destination topic nor the arrow
|
||||||
@ -31,89 +31,88 @@ const MoveControlPointCommand = new Class(
|
|||||||
* @param ctrlPointController {ControlPoint}
|
* @param ctrlPointController {ControlPoint}
|
||||||
* @param point {Number} 0 for the destination control point, 1 for the source control point
|
* @param point {Number} 0 for the destination control point, 1 for the source control point
|
||||||
*/
|
*/
|
||||||
initialize: function (ctrlPointController, point) {
|
initialize(ctrlPointController, point) {
|
||||||
$assert(ctrlPointController, 'line can not be null');
|
$assert(ctrlPointController, 'line can not be null');
|
||||||
$assert($defined(point), 'point can not be null');
|
$assert($defined(point), 'point can not be null');
|
||||||
|
|
||||||
this.parent();
|
this.parent();
|
||||||
this._ctrlPointControler = ctrlPointController;
|
this._ctrlPointControler = ctrlPointController;
|
||||||
this._line = ctrlPointController._line;
|
this._line = ctrlPointController._line;
|
||||||
this._controlPoint = this._ctrlPointControler.getControlPoint(point).clone();
|
this._controlPoint = this._ctrlPointControler.getControlPoint(point).clone();
|
||||||
this._oldControlPoint = this._ctrlPointControler.getOriginalCtrlPoint(point).clone();
|
this._oldControlPoint = this._ctrlPointControler.getOriginalCtrlPoint(point).clone();
|
||||||
this._originalEndPoint = this._ctrlPointControler.getOriginalEndPoint(point).clone();
|
this._originalEndPoint = this._ctrlPointControler.getOriginalEndPoint(point).clone();
|
||||||
switch (point) {
|
switch (point) {
|
||||||
case 0:
|
case 0:
|
||||||
this._wasCustom = this._line.getLine().isSrcControlPointCustom();
|
this._wasCustom = this._line.getLine().isSrcControlPointCustom();
|
||||||
this._endPoint = this._line.getLine().getFrom().clone();
|
this._endPoint = this._line.getLine().getFrom().clone();
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
this._wasCustom = this._line.getLine().isDestControlPointCustom();
|
this._wasCustom = this._line.getLine().isDestControlPointCustom();
|
||||||
this._endPoint = this._line.getLine().getTo().clone();
|
this._endPoint = this._line.getLine().getTo().clone();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this._point = point;
|
this._point = point;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides abstract parent method
|
* Overrides abstract parent method
|
||||||
*/
|
*/
|
||||||
execute: function (commandContext) {
|
execute(commandContext) {
|
||||||
var model = this._line.getModel();
|
const model = this._line.getModel();
|
||||||
switch (this._point) {
|
switch (this._point) {
|
||||||
case 0:
|
case 0:
|
||||||
model.setSrcCtrlPoint(this._controlPoint.clone());
|
model.setSrcCtrlPoint(this._controlPoint.clone());
|
||||||
this._line.setFrom(this._endPoint.x, this._endPoint.y);
|
this._line.setFrom(this._endPoint.x, this._endPoint.y);
|
||||||
this._line.setIsSrcControlPointCustom(true);
|
this._line.setIsSrcControlPointCustom(true);
|
||||||
this._line.setSrcControlPoint(this._controlPoint.clone());
|
this._line.setSrcControlPoint(this._controlPoint.clone());
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
model.setDestCtrlPoint(this._controlPoint.clone());
|
model.setDestCtrlPoint(this._controlPoint.clone());
|
||||||
this._wasCustom = this._line.getLine().isDestControlPointCustom();
|
this._wasCustom = this._line.getLine().isDestControlPointCustom();
|
||||||
this._line.setTo(this._endPoint.x, this._endPoint.y);
|
this._line.setTo(this._endPoint.x, this._endPoint.y);
|
||||||
this._line.setIsDestControlPointCustom(true);
|
this._line.setIsDestControlPointCustom(true);
|
||||||
this._line.setDestControlPoint(this._controlPoint.clone());
|
this._line.setDestControlPoint(this._controlPoint.clone());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (this._line.isOnFocus()) {
|
if (this._line.isOnFocus()) {
|
||||||
this._line._refreshShape();
|
this._line._refreshShape();
|
||||||
this._ctrlPointControler.setLine(this._line);
|
this._ctrlPointControler.setLine(this._line);
|
||||||
}
|
}
|
||||||
this._line.getLine().updateLine(this._point);
|
this._line.getLine().updateLine(this._point);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides abstract parent method
|
* Overrides abstract parent method
|
||||||
* @see {@link mindplot.Command.undoExecute}
|
* @see {@link mindplot.Command.undoExecute}
|
||||||
*/
|
*/
|
||||||
undoExecute: function (commandContext) {
|
undoExecute(commandContext) {
|
||||||
var line = this._line;
|
const line = this._line;
|
||||||
var model = line.getModel();
|
const model = line.getModel();
|
||||||
switch (this._point) {
|
switch (this._point) {
|
||||||
case 0:
|
case 0:
|
||||||
if ($defined(this._oldControlPoint)) {
|
if ($defined(this._oldControlPoint)) {
|
||||||
line.setFrom(this._originalEndPoint.x, this._originalEndPoint.y);
|
line.setFrom(this._originalEndPoint.x, this._originalEndPoint.y);
|
||||||
model.setSrcCtrlPoint(this._oldControlPoint.clone());
|
model.setSrcCtrlPoint(this._oldControlPoint.clone());
|
||||||
line.setSrcControlPoint(this._oldControlPoint.clone());
|
line.setSrcControlPoint(this._oldControlPoint.clone());
|
||||||
line.setIsSrcControlPointCustom(this._wasCustom);
|
line.setIsSrcControlPointCustom(this._wasCustom);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if ($defined(this._oldControlPoint)) {
|
if ($defined(this._oldControlPoint)) {
|
||||||
line.setTo(this._originalEndPoint.x, this._originalEndPoint.y);
|
line.setTo(this._originalEndPoint.x, this._originalEndPoint.y);
|
||||||
model.setDestCtrlPoint(this._oldControlPoint.clone());
|
model.setDestCtrlPoint(this._oldControlPoint.clone());
|
||||||
line.setDestControlPoint(this._oldControlPoint.clone());
|
line.setDestControlPoint(this._oldControlPoint.clone());
|
||||||
line.setIsDestControlPointCustom(this._wasCustom);
|
line.setIsDestControlPointCustom(this._wasCustom);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this._line.getLine().updateLine(this._point);
|
this._line.getLine().updateLine(this._point);
|
||||||
if (this._line.isOnFocus()) {
|
if (this._line.isOnFocus()) {
|
||||||
this._ctrlPointControler.setLine(line);
|
this._ctrlPointControler.setLine(line);
|
||||||
line._refreshShape();
|
line._refreshShape();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
export default MoveControlPointCommand;
|
export default MoveControlPointCommand;
|
||||||
|
|
||||||
|
@ -17,9 +17,9 @@
|
|||||||
*/
|
*/
|
||||||
const Command = require('../Command').default;
|
const Command = require('../Command').default;
|
||||||
|
|
||||||
const RemoveFeatureFromTopicCommand = new Class(/**@lends RemoveFeatureFromTopicCommand */{
|
const RemoveFeatureFromTopicCommand = new Class(/** @lends RemoveFeatureFromTopicCommand */{
|
||||||
Extends:Command,
|
Extends: Command,
|
||||||
/**
|
/**
|
||||||
* @classdesc This command handles do/undo of removing a feature from a topic, e.g. an icon or
|
* @classdesc This command handles do/undo of removing a feature from a topic, e.g. an icon or
|
||||||
* a note. For a reference of existing features, refer to {@link mindplot.TopicFeature}.
|
* a note. For a reference of existing features, refer to {@link mindplot.TopicFeature}.
|
||||||
* @constructs
|
* @constructs
|
||||||
@ -27,35 +27,35 @@ const RemoveFeatureFromTopicCommand = new Class(/**@lends RemoveFeatureFromTopic
|
|||||||
* @param {String} featureId id of the feature to remove
|
* @param {String} featureId id of the feature to remove
|
||||||
* @extends mindplot.Command
|
* @extends mindplot.Command
|
||||||
*/
|
*/
|
||||||
initialize:function (topicId, featureId) {
|
initialize(topicId, featureId) {
|
||||||
$assert($defined(topicId), 'topicId can not be null');
|
$assert($defined(topicId), 'topicId can not be null');
|
||||||
$assert(featureId, 'iconModel can not be null');
|
$assert(featureId, 'iconModel can not be null');
|
||||||
|
|
||||||
this.parent();
|
this.parent();
|
||||||
this._topicId = topicId;
|
this._topicId = topicId;
|
||||||
this._featureId = featureId;
|
this._featureId = featureId;
|
||||||
this._oldFeature = null;
|
this._oldFeature = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides abstract parent method
|
* Overrides abstract parent method
|
||||||
*/
|
*/
|
||||||
execute:function (commandContext) {
|
execute(commandContext) {
|
||||||
var topic = commandContext.findTopics(this._topicId)[0];
|
const topic = commandContext.findTopics(this._topicId)[0];
|
||||||
var feature = topic.findFeatureById(this._featureId);
|
const feature = topic.findFeatureById(this._featureId);
|
||||||
topic.removeFeature(feature);
|
topic.removeFeature(feature);
|
||||||
this._oldFeature = feature;
|
this._oldFeature = feature;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides abstract parent method
|
* Overrides abstract parent method
|
||||||
* @see {@link mindplot.Command.undoExecute}
|
* @see {@link mindplot.Command.undoExecute}
|
||||||
*/
|
*/
|
||||||
undoExecute:function (commandContext) {
|
undoExecute(commandContext) {
|
||||||
var topic = commandContext.findTopics(this._topicId)[0];
|
const topic = commandContext.findTopics(this._topicId)[0];
|
||||||
topic.addFeature(this._oldFeature);
|
topic.addFeature(this._oldFeature);
|
||||||
this._oldFeature = null;
|
this._oldFeature = null;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default RemoveFeatureFromTopicCommand;
|
export default RemoveFeatureFromTopicCommand;
|
||||||
|
@ -9,13 +9,13 @@ const moveControlPointCommand = require('./MoveControlPointCommand').default;
|
|||||||
const removeFeatureFromTopicCommand = require('./RemoveFeatureFromTopicCommand').default;
|
const removeFeatureFromTopicCommand = require('./RemoveFeatureFromTopicCommand').default;
|
||||||
|
|
||||||
export const Commands = {
|
export const Commands = {
|
||||||
AddFeatureToTopicCommand: addFeatureToTopicCommand,
|
AddFeatureToTopicCommand: addFeatureToTopicCommand,
|
||||||
AddRelationshipCommand: addRelationshipCommand,
|
AddRelationshipCommand: addRelationshipCommand,
|
||||||
AddTopicCommand: addTopicCommand,
|
AddTopicCommand: addTopicCommand,
|
||||||
ChangeFeatureToTopicCommand: changeFeatureToTopicCommand,
|
ChangeFeatureToTopicCommand: changeFeatureToTopicCommand,
|
||||||
DeleteCommand: deleteCommand,
|
DeleteCommand: deleteCommand,
|
||||||
DragTopicCommand: dragTopicCommand,
|
DragTopicCommand: dragTopicCommand,
|
||||||
GenericFunctionCommand: genericFunctionCommand,
|
GenericFunctionCommand: genericFunctionCommand,
|
||||||
MoveControlPointCommand: moveControlPointCommand,
|
MoveControlPointCommand: moveControlPointCommand,
|
||||||
RemoveFeatureFromTopicCommand: removeFeatureFromTopicCommand,
|
RemoveFeatureFromTopicCommand: removeFeatureFromTopicCommand,
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
try {
|
try {
|
||||||
$(document).trigger('loadcomplete', 'mind');
|
$(document).trigger('loadcomplete', 'mind');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e.stack);
|
console.error(e.stack);
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var mindplot = {};
|
const mindplot = {};
|
||||||
mindplot.util = {};
|
mindplot.util = {};
|
||||||
mindplot.commands = {};
|
mindplot.commands = {};
|
||||||
mindplot.layout = {};
|
mindplot.layout = {};
|
||||||
@ -31,5 +31,5 @@ mindplot.persistence = {};
|
|||||||
mindplot.layout = {};
|
mindplot.layout = {};
|
||||||
|
|
||||||
Class.Mutators.Static = function (items) {
|
Class.Mutators.Static = function (items) {
|
||||||
this.extend(items);
|
this.extend(items);
|
||||||
};
|
};
|
||||||
|
@ -50,59 +50,59 @@ const topicStyle = require('./TopicStyle').default;
|
|||||||
const workspace = require('./Workspace').default;
|
const workspace = require('./Workspace').default;
|
||||||
|
|
||||||
export const Components = {
|
export const Components = {
|
||||||
ActionDispatcher: actionDispatcher,
|
ActionDispatcher: actionDispatcher,
|
||||||
|
|
||||||
ActionIcon: actionIcon,
|
ActionIcon: actionIcon,
|
||||||
CentralTopic: centralTopic,
|
CentralTopic: centralTopic,
|
||||||
Command: command,
|
Command: command,
|
||||||
ConnectionLine: connectionLine,
|
ConnectionLine: connectionLine,
|
||||||
ControlPoint: controlPoint,
|
ControlPoint: controlPoint,
|
||||||
Designer: designer,
|
Designer: designer,
|
||||||
|
|
||||||
DesignerActionRunner: designerActionRunner,
|
DesignerActionRunner: designerActionRunner,
|
||||||
DesignerKeyboard: designerKeyboard,
|
DesignerKeyboard: designerKeyboard,
|
||||||
DesignerModel: designerModal,
|
DesignerModel: designerModal,
|
||||||
DesignerUndoManager: designerUndoManager,
|
DesignerUndoManager: designerUndoManager,
|
||||||
|
|
||||||
DragConnector: dragConnector,
|
DragConnector: dragConnector,
|
||||||
DragManager: dragManager,
|
DragManager: dragManager,
|
||||||
DragPivot: dragPivot,
|
DragPivot: dragPivot,
|
||||||
DragTopic: dragTopic,
|
DragTopic: dragTopic,
|
||||||
EditorOptions: editorOptions,
|
EditorOptions: editorOptions,
|
||||||
EditorProperties: editorProperties,
|
EditorProperties: editorProperties,
|
||||||
Events: events,
|
Events: events,
|
||||||
|
|
||||||
footer: footer,
|
footer,
|
||||||
header: header,
|
header,
|
||||||
|
|
||||||
Icon: icon,
|
Icon: icon,
|
||||||
IconGroup: iconGroup,
|
IconGroup: iconGroup,
|
||||||
ImageIcon: imageIcon,
|
ImageIcon: imageIcon,
|
||||||
Keyboard: keyboard,
|
Keyboard: keyboard,
|
||||||
LinkIcon: linkIcon,
|
LinkIcon: linkIcon,
|
||||||
|
|
||||||
localSorageManager: localSorageManager,
|
localSorageManager,
|
||||||
MainTopic: mainTopic,
|
MainTopic: mainTopic,
|
||||||
|
|
||||||
Messages: messages,
|
Messages: messages,
|
||||||
MultilineTextEditor: multilineTextEditor,
|
MultilineTextEditor: multilineTextEditor,
|
||||||
NodeGraph: nodeGraph,
|
NodeGraph: nodeGraph,
|
||||||
NoteIcon: noteIcon,
|
NoteIcon: noteIcon,
|
||||||
Options: options,
|
Options: options,
|
||||||
|
|
||||||
PersistenceManager: persistenceManager,
|
PersistenceManager: persistenceManager,
|
||||||
Relationship: relationship,
|
Relationship: relationship,
|
||||||
RelationshipPivot: relationshipPivot,
|
RelationshipPivot: relationshipPivot,
|
||||||
RestPersistenceManager: resetPersistenceManager,
|
RestPersistenceManager: resetPersistenceManager,
|
||||||
ScreenManager: screenManager,
|
ScreenManager: screenManager,
|
||||||
ShrinkConnector: shrinkConnector,
|
ShrinkConnector: shrinkConnector,
|
||||||
StandaloneActionDispatcher: standaloneActionDispatcher,
|
StandaloneActionDispatcher: standaloneActionDispatcher,
|
||||||
TextEditor: textEditor,
|
TextEditor: textEditor,
|
||||||
TextEditorFactory: textEditorFactory,
|
TextEditorFactory: textEditorFactory,
|
||||||
|
|
||||||
Topic: topic,
|
Topic: topic,
|
||||||
TopicEventDispatcher: topicEventDispatcher,
|
TopicEventDispatcher: topicEventDispatcher,
|
||||||
TopicFeature: topicFeature,
|
TopicFeature: topicFeature,
|
||||||
TopicStyle: topicStyle,
|
TopicStyle: topicStyle,
|
||||||
Workspace: workspace,
|
Workspace: workspace,
|
||||||
};
|
};
|
||||||
|
@ -22,64 +22,62 @@ const ChildrenSorterStrategy = require('./ChildrenSorterStrategy').default;
|
|||||||
* @extends mindplot.layout.ChildrenSorterStrategy
|
* @extends mindplot.layout.ChildrenSorterStrategy
|
||||||
*/
|
*/
|
||||||
const AbstractBasicSorter = new Class(
|
const AbstractBasicSorter = new Class(
|
||||||
/** @lends AbstractBasicSorter */ {
|
/** @lends AbstractBasicSorter */ {
|
||||||
Extends: ChildrenSorterStrategy,
|
Extends: ChildrenSorterStrategy,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {} treeSet
|
* @param {} treeSet
|
||||||
* @param {} node
|
* @param {} node
|
||||||
* @return the height of a node and its children if existing and not shrunken
|
* @return the height of a node and its children if existing and not shrunken
|
||||||
*/
|
*/
|
||||||
computeChildrenIdByHeights: function (treeSet, node) {
|
computeChildrenIdByHeights(treeSet, node) {
|
||||||
var result = {};
|
const result = {};
|
||||||
this._computeChildrenHeight(treeSet, node, result);
|
this._computeChildrenHeight(treeSet, node, result);
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
_getVerticalPadding: function () {
|
_getVerticalPadding() {
|
||||||
return AbstractBasicSorter.INTERNODE_VERTICAL_PADDING;
|
return AbstractBasicSorter.INTERNODE_VERTICAL_PADDING;
|
||||||
},
|
},
|
||||||
|
|
||||||
_computeChildrenHeight: function (treeSet, node, heightCache) {
|
_computeChildrenHeight(treeSet, node, heightCache) {
|
||||||
var height = node.getSize().height + this._getVerticalPadding() * 2; // 2* Top and down padding;
|
const height = node.getSize().height + this._getVerticalPadding() * 2; // 2* Top and down padding;
|
||||||
|
|
||||||
var result;
|
let result;
|
||||||
var children = treeSet.getChildren(node);
|
const children = treeSet.getChildren(node);
|
||||||
if (children.length == 0 || node.areChildrenShrunken()) {
|
if (children.length == 0 || node.areChildrenShrunken()) {
|
||||||
result = height;
|
result = height;
|
||||||
} else {
|
} else {
|
||||||
var childrenHeight = 0;
|
let childrenHeight = 0;
|
||||||
_.each(
|
_.each(
|
||||||
children,
|
children,
|
||||||
function (child) {
|
function (child) {
|
||||||
childrenHeight += this._computeChildrenHeight(treeSet, child, heightCache);
|
childrenHeight += this._computeChildrenHeight(treeSet, child, heightCache);
|
||||||
},
|
},
|
||||||
this
|
this,
|
||||||
);
|
);
|
||||||
|
|
||||||
result = Math.max(height, childrenHeight);
|
result = Math.max(height, childrenHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (heightCache) {
|
if (heightCache) {
|
||||||
heightCache[node.getId()] = result;
|
heightCache[node.getId()] = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
_getSortedChildren: function (treeSet, node) {
|
_getSortedChildren(treeSet, node) {
|
||||||
var result = treeSet.getChildren(node);
|
const result = treeSet.getChildren(node);
|
||||||
result.sort(function (a, b) {
|
result.sort((a, b) => a.getOrder() - b.getOrder());
|
||||||
return a.getOrder() - b.getOrder();
|
return result;
|
||||||
});
|
},
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
_getRelativeDirection: function (reference, position) {
|
_getRelativeDirection(reference, position) {
|
||||||
var offset = position.x - reference.x;
|
const offset = position.x - reference.x;
|
||||||
return offset >= 0 ? 1 : -1;
|
return offset >= 0 ? 1 : -1;
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -18,15 +18,15 @@
|
|||||||
const AbstractBasicSorter = require('./AbstractBasicSorter').default;
|
const AbstractBasicSorter = require('./AbstractBasicSorter').default;
|
||||||
|
|
||||||
const BalancedSorter = new Class(
|
const BalancedSorter = new Class(
|
||||||
/** @lends BalancedSorter */ {
|
/** @lends BalancedSorter */ {
|
||||||
Extends: AbstractBasicSorter,
|
Extends: AbstractBasicSorter,
|
||||||
/**
|
/**
|
||||||
* @constructs
|
* @constructs
|
||||||
* @extends mindplot.layout.AbstractBasicSorter
|
* @extends mindplot.layout.AbstractBasicSorter
|
||||||
*/
|
*/
|
||||||
initialize: function () {},
|
initialize() {},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {} graph
|
* @param {} graph
|
||||||
* @param {} parent
|
* @param {} parent
|
||||||
* @param {} node
|
* @param {} node
|
||||||
@ -34,294 +34,286 @@ const BalancedSorter = new Class(
|
|||||||
* @param {Boolean} free
|
* @param {Boolean} free
|
||||||
* @return an array with order and position
|
* @return an array with order and position
|
||||||
*/
|
*/
|
||||||
predict: function (graph, parent, node, position, free) {
|
predict(graph, parent, node, position, free) {
|
||||||
// If its a free node...
|
// If its a free node...
|
||||||
if (free) {
|
if (free) {
|
||||||
$assert(
|
$assert(
|
||||||
$defined(position),
|
$defined(position),
|
||||||
'position cannot be null for predict in free positioning'
|
'position cannot be null for predict in free positioning',
|
||||||
);
|
);
|
||||||
$assert($defined(node), 'node cannot be null for predict in free positioning');
|
$assert($defined(node), 'node cannot be null for predict in free positioning');
|
||||||
|
|
||||||
var rootNode = graph.getRootNode(parent);
|
var rootNode = graph.getRootNode(parent);
|
||||||
var direction = this._getRelativeDirection(
|
var direction = this._getRelativeDirection(
|
||||||
rootNode.getPosition(),
|
rootNode.getPosition(),
|
||||||
node.getPosition()
|
node.getPosition(),
|
||||||
);
|
);
|
||||||
|
|
||||||
var limitXPos =
|
const limitXPos = parent.getPosition().x
|
||||||
parent.getPosition().x +
|
+ direction
|
||||||
direction *
|
* (parent.getSize().width / 2
|
||||||
(parent.getSize().width / 2 +
|
+ node.getSize().width / 2
|
||||||
node.getSize().width / 2 +
|
+ BalancedSorter.INTERNODE_HORIZONTAL_PADDING);
|
||||||
BalancedSorter.INTERNODE_HORIZONTAL_PADDING);
|
|
||||||
|
|
||||||
var xPos =
|
const xPos = direction > 0
|
||||||
direction > 0
|
? position.x >= limitXPos
|
||||||
? position.x >= limitXPos
|
? position.x
|
||||||
? position.x
|
: limitXPos
|
||||||
: limitXPos
|
: position.x <= limitXPos
|
||||||
: position.x <= limitXPos
|
? position.x
|
||||||
? position.x
|
: limitXPos;
|
||||||
: limitXPos;
|
|
||||||
|
|
||||||
return [0, { x: xPos, y: position.y }];
|
return [0, { x: xPos, y: position.y }];
|
||||||
}
|
}
|
||||||
|
|
||||||
var rootNode = graph.getRootNode(parent);
|
var rootNode = graph.getRootNode(parent);
|
||||||
|
|
||||||
// If it is a dragged node...
|
// If it is a dragged node...
|
||||||
if (node) {
|
if (node) {
|
||||||
$assert($defined(position), 'position cannot be null for predict in dragging');
|
$assert($defined(position), 'position cannot be null for predict in dragging');
|
||||||
var nodeDirection = this._getRelativeDirection(
|
const nodeDirection = this._getRelativeDirection(
|
||||||
rootNode.getPosition(),
|
rootNode.getPosition(),
|
||||||
node.getPosition()
|
node.getPosition(),
|
||||||
);
|
);
|
||||||
var positionDirection = this._getRelativeDirection(
|
const positionDirection = this._getRelativeDirection(
|
||||||
rootNode.getPosition(),
|
rootNode.getPosition(),
|
||||||
position
|
position,
|
||||||
);
|
);
|
||||||
var siblings = graph.getSiblings(node);
|
const siblings = graph.getSiblings(node);
|
||||||
|
|
||||||
var sameParent = parent == graph.getParent(node);
|
const sameParent = parent == graph.getParent(node);
|
||||||
if (siblings.length == 0 && nodeDirection == positionDirection && sameParent) {
|
if (siblings.length == 0 && nodeDirection == positionDirection && sameParent) {
|
||||||
return [node.getOrder(), node.getPosition()];
|
return [node.getOrder(), node.getPosition()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!position) {
|
if (!position) {
|
||||||
var right = this._getChildrenForOrder(parent, graph, 0);
|
var right = this._getChildrenForOrder(parent, graph, 0);
|
||||||
var left = this._getChildrenForOrder(parent, graph, 1);
|
var left = this._getChildrenForOrder(parent, graph, 1);
|
||||||
}
|
}
|
||||||
// Filter nodes on one side..
|
// Filter nodes on one side..
|
||||||
var order = position
|
const order = position
|
||||||
? position.x > rootNode.getPosition().x
|
? position.x > rootNode.getPosition().x
|
||||||
? 0
|
? 0
|
||||||
: 1
|
: 1
|
||||||
: right.length - left.length > 0
|
: right.length - left.length > 0
|
||||||
? 1
|
? 1
|
||||||
: 0;
|
: 0;
|
||||||
var direction = order % 2 == 0 ? 1 : -1;
|
var direction = order % 2 == 0 ? 1 : -1;
|
||||||
|
|
||||||
// Exclude the dragged node (if set)
|
// Exclude the dragged node (if set)
|
||||||
var children = this._getChildrenForOrder(parent, graph, order).filter(function (child) {
|
const children = this._getChildrenForOrder(parent, graph, order).filter((child) => child != node);
|
||||||
return child != node;
|
|
||||||
});
|
|
||||||
|
|
||||||
// No children?
|
// No children?
|
||||||
if (children.length == 0) {
|
if (children.length == 0) {
|
||||||
return [
|
return [
|
||||||
order,
|
order,
|
||||||
{
|
{
|
||||||
x:
|
x:
|
||||||
parent.getPosition().x +
|
parent.getPosition().x
|
||||||
direction *
|
+ direction
|
||||||
(parent.getSize().width / 2 +
|
* (parent.getSize().width / 2
|
||||||
BalancedSorter.INTERNODE_HORIZONTAL_PADDING * 2),
|
+ BalancedSorter.INTERNODE_HORIZONTAL_PADDING * 2),
|
||||||
y: parent.getPosition().y,
|
y: parent.getPosition().y,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to fit within ...
|
// Try to fit within ...
|
||||||
var result = null;
|
let result = null;
|
||||||
var last = children.getLast();
|
const last = children.getLast();
|
||||||
position = position || { x: last.getPosition().x, y: last.getPosition().y + 1 };
|
position = position || { x: last.getPosition().x, y: last.getPosition().y + 1 };
|
||||||
_.each(children, function (child, index) {
|
_.each(children, (child, index) => {
|
||||||
var cpos = child.getPosition();
|
const cpos = child.getPosition();
|
||||||
if (position.y > cpos.y) {
|
if (position.y > cpos.y) {
|
||||||
let yOffset =
|
const yOffset = child == last
|
||||||
child == last
|
? child.getSize().height + BalancedSorter.INTERNODE_VERTICAL_PADDING * 2
|
||||||
? child.getSize().height + BalancedSorter.INTERNODE_VERTICAL_PADDING * 2
|
: (children[index + 1].getPosition().y - child.getPosition().y) / 2;
|
||||||
: (children[index + 1].getPosition().y - child.getPosition().y) / 2;
|
result = [child.getOrder() + 2, { x: cpos.x, y: cpos.y + yOffset }];
|
||||||
result = [child.getOrder() + 2, { x: cpos.x, y: cpos.y + yOffset }];
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
// Position wasn't below any node, so it must be inserted above
|
// Position wasn't below any node, so it must be inserted above
|
||||||
if (!result) {
|
if (!result) {
|
||||||
var first = children[0];
|
const first = children[0];
|
||||||
result = [
|
result = [
|
||||||
position.x > 0 ? 0 : 1,
|
position.x > 0 ? 0 : 1,
|
||||||
{
|
{
|
||||||
x: first.getPosition().x,
|
x: first.getPosition().x,
|
||||||
y:
|
y:
|
||||||
first.getPosition().y -
|
first.getPosition().y
|
||||||
first.getSize().height -
|
- first.getSize().height
|
||||||
BalancedSorter.INTERNODE_VERTICAL_PADDING * 2,
|
- BalancedSorter.INTERNODE_VERTICAL_PADDING * 2,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {} treeSet
|
* @param {} treeSet
|
||||||
* @param {} parent
|
* @param {} parent
|
||||||
* @param {} child
|
* @param {} child
|
||||||
* @param {} order
|
* @param {} order
|
||||||
*/
|
*/
|
||||||
insert: function (treeSet, parent, child, order) {
|
insert(treeSet, parent, child, order) {
|
||||||
var children = this._getChildrenForOrder(parent, treeSet, order);
|
const children = this._getChildrenForOrder(parent, treeSet, order);
|
||||||
|
|
||||||
// If no children, return 0 or 1 depending on the side
|
// If no children, return 0 or 1 depending on the side
|
||||||
if (children.length == 0) {
|
if (children.length == 0) {
|
||||||
child.setOrder(order % 2);
|
child.setOrder(order % 2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shift all the elements by two, so side is the same.
|
// Shift all the elements by two, so side is the same.
|
||||||
// In case of balanced sorter, order don't need to be continuous...
|
// In case of balanced sorter, order don't need to be continuous...
|
||||||
var max = 0;
|
let max = 0;
|
||||||
for (var i = 0; i < children.length; i++) {
|
for (let i = 0; i < children.length; i++) {
|
||||||
var node = children[i];
|
const node = children[i];
|
||||||
max = Math.max(max, node.getOrder());
|
max = Math.max(max, node.getOrder());
|
||||||
if (node.getOrder() >= order) {
|
if (node.getOrder() >= order) {
|
||||||
max = Math.max(max, node.getOrder() + 2);
|
max = Math.max(max, node.getOrder() + 2);
|
||||||
node.setOrder(node.getOrder() + 2);
|
node.setOrder(node.getOrder() + 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var newOrder = order > max + 1 ? max + 2 : order;
|
const newOrder = order > max + 1 ? max + 2 : order;
|
||||||
child.setOrder(newOrder);
|
child.setOrder(newOrder);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {} treeSet
|
* @param {} treeSet
|
||||||
* @param {} node
|
* @param {} node
|
||||||
*/
|
*/
|
||||||
detach: function (treeSet, node) {
|
detach(treeSet, node) {
|
||||||
var parent = treeSet.getParent(node);
|
const parent = treeSet.getParent(node);
|
||||||
// Filter nodes on one side..
|
// Filter nodes on one side..
|
||||||
var children = this._getChildrenForOrder(parent, treeSet, node.getOrder());
|
const children = this._getChildrenForOrder(parent, treeSet, node.getOrder());
|
||||||
|
|
||||||
_.each(children, function (child, index) {
|
_.each(children, (child, index) => {
|
||||||
if (child.getOrder() > node.getOrder()) {
|
if (child.getOrder() > node.getOrder()) {
|
||||||
child.setOrder(child.getOrder() - 2);
|
child.setOrder(child.getOrder() - 2);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
node.setOrder(node.getOrder() % 2 == 0 ? 0 : 1);
|
node.setOrder(node.getOrder() % 2 == 0 ? 0 : 1);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {} treeSet
|
* @param {} treeSet
|
||||||
* @param {} node
|
* @param {} node
|
||||||
* @return offsets
|
* @return offsets
|
||||||
*/
|
*/
|
||||||
computeOffsets: function (treeSet, node) {
|
computeOffsets(treeSet, node) {
|
||||||
$assert(treeSet, 'treeSet can no be null.');
|
$assert(treeSet, 'treeSet can no be null.');
|
||||||
$assert(node, 'node can no be null.');
|
$assert(node, 'node can no be null.');
|
||||||
|
|
||||||
var children = this._getSortedChildren(treeSet, node);
|
const children = this._getSortedChildren(treeSet, node);
|
||||||
|
|
||||||
// Compute heights ...
|
// Compute heights ...
|
||||||
var heights = children
|
const heights = children
|
||||||
.map(function (child) {
|
.map(function (child) {
|
||||||
return {
|
return {
|
||||||
id: child.getId(),
|
id: child.getId(),
|
||||||
order: child.getOrder(),
|
order: child.getOrder(),
|
||||||
width: child.getSize().width,
|
width: child.getSize().width,
|
||||||
height: this._computeChildrenHeight(treeSet, child),
|
height: this._computeChildrenHeight(treeSet, child),
|
||||||
};
|
};
|
||||||
}, this)
|
}, this)
|
||||||
.reverse();
|
.reverse();
|
||||||
|
|
||||||
// Compute the center of the branch ...
|
// Compute the center of the branch ...
|
||||||
var totalPHeight = 0;
|
let totalPHeight = 0;
|
||||||
var totalNHeight = 0;
|
let totalNHeight = 0;
|
||||||
|
|
||||||
_.each(heights, function (elem) {
|
_.each(heights, (elem) => {
|
||||||
if (elem.order % 2 == 0) {
|
if (elem.order % 2 == 0) {
|
||||||
totalPHeight += elem.height;
|
totalPHeight += elem.height;
|
||||||
} else {
|
} else {
|
||||||
totalNHeight += elem.height;
|
totalNHeight += elem.height;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var psum = totalPHeight / 2;
|
let psum = totalPHeight / 2;
|
||||||
var nsum = totalNHeight / 2;
|
let nsum = totalNHeight / 2;
|
||||||
var ysum = 0;
|
let ysum = 0;
|
||||||
|
|
||||||
// Calculate the offsets ...
|
// Calculate the offsets ...
|
||||||
var result = {};
|
const result = {};
|
||||||
for (var i = 0; i < heights.length; i++) {
|
for (let i = 0; i < heights.length; i++) {
|
||||||
var direction = heights[i].order % 2 ? -1 : 1;
|
const direction = heights[i].order % 2 ? -1 : 1;
|
||||||
|
|
||||||
if (direction > 0) {
|
if (direction > 0) {
|
||||||
psum = psum - heights[i].height;
|
psum -= heights[i].height;
|
||||||
ysum = psum;
|
ysum = psum;
|
||||||
} else {
|
} else {
|
||||||
nsum = nsum - heights[i].height;
|
nsum -= heights[i].height;
|
||||||
ysum = nsum;
|
ysum = nsum;
|
||||||
}
|
}
|
||||||
|
|
||||||
var yOffset = ysum + heights[i].height / 2;
|
const yOffset = ysum + heights[i].height / 2;
|
||||||
var xOffset =
|
const xOffset = direction
|
||||||
direction *
|
* (node.getSize().width / 2
|
||||||
(node.getSize().width / 2 +
|
+ heights[i].width / 2
|
||||||
heights[i].width / 2 +
|
+ +BalancedSorter.INTERNODE_HORIZONTAL_PADDING);
|
||||||
+BalancedSorter.INTERNODE_HORIZONTAL_PADDING);
|
|
||||||
|
|
||||||
$assert(!isNaN(xOffset), 'xOffset can not be null');
|
$assert(!isNaN(xOffset), 'xOffset can not be null');
|
||||||
$assert(!isNaN(yOffset), 'yOffset can not be null');
|
$assert(!isNaN(yOffset), 'yOffset can not be null');
|
||||||
|
|
||||||
result[heights[i].id] = { x: xOffset, y: yOffset };
|
result[heights[i].id] = { x: xOffset, y: yOffset };
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {} treeSet
|
* @param {} treeSet
|
||||||
* @param {} node
|
* @param {} node
|
||||||
* @throw will throw an error if order elements are missing
|
* @throw will throw an error if order elements are missing
|
||||||
*/
|
*/
|
||||||
verify: function (treeSet, node) {
|
verify(treeSet, node) {
|
||||||
// Check that all is consistent ...
|
// Check that all is consistent ...
|
||||||
var children = this._getChildrenForOrder(node, treeSet, node.getOrder());
|
const children = this._getChildrenForOrder(node, treeSet, node.getOrder());
|
||||||
|
|
||||||
// All odd ordered nodes should be "continuous" by themselves
|
// All odd ordered nodes should be "continuous" by themselves
|
||||||
// All even numbered nodes should be "continuous" by themselves
|
// All even numbered nodes should be "continuous" by themselves
|
||||||
var factor = node.getOrder() % 2 == 0 ? 2 : 1;
|
const factor = node.getOrder() % 2 == 0 ? 2 : 1;
|
||||||
for (var i = 0; i < children.length; i++) {
|
for (let i = 0; i < children.length; i++) {
|
||||||
var order = i == 0 && factor == 1 ? 1 : factor * i;
|
const order = i == 0 && factor == 1 ? 1 : factor * i;
|
||||||
$assert(
|
$assert(
|
||||||
children[i].getOrder() == order,
|
children[i].getOrder() == order,
|
||||||
'Missing order elements. Missing order: ' +
|
`Missing order elements. Missing order: ${
|
||||||
i * factor +
|
i * factor
|
||||||
'. Parent:' +
|
}. Parent:${
|
||||||
node.getId() +
|
node.getId()
|
||||||
',Node:' +
|
},Node:${
|
||||||
children[i].getId()
|
children[i].getId()}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {} treeSet
|
* @param {} treeSet
|
||||||
* @param {} child
|
* @param {} child
|
||||||
* @return the direction of the child within the treeSet
|
* @return the direction of the child within the treeSet
|
||||||
*/
|
*/
|
||||||
getChildDirection: function (treeSet, child) {
|
getChildDirection(treeSet, child) {
|
||||||
return child.getOrder() % 2 == 0 ? 1 : -1;
|
return child.getOrder() % 2 == 0 ? 1 : -1;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {String} the print name of this class
|
* @return {String} the print name of this class
|
||||||
*/
|
*/
|
||||||
toString: function () {
|
toString() {
|
||||||
return 'Balanced Sorter';
|
return 'Balanced Sorter';
|
||||||
},
|
},
|
||||||
|
|
||||||
_getChildrenForOrder: function (parent, graph, order) {
|
_getChildrenForOrder(parent, graph, order) {
|
||||||
return this._getSortedChildren(graph, parent).filter(function (child) {
|
return this._getSortedChildren(graph, parent).filter((child) => child.getOrder() % 2 == order % 2);
|
||||||
return child.getOrder() % 2 == order % 2;
|
},
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
_getVerticalPadding: function () {
|
_getVerticalPadding() {
|
||||||
return BalancedSorter.INTERNODE_VERTICAL_PADDING;
|
return BalancedSorter.INTERNODE_VERTICAL_PADDING;
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,54 +17,54 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const ChangeEvent = new Class(/** @lends ChangeEvent */{
|
const ChangeEvent = new Class(/** @lends ChangeEvent */{
|
||||||
/**
|
/**
|
||||||
* @constructs
|
* @constructs
|
||||||
* @param {} id
|
* @param {} id
|
||||||
* @throws will throw an error if the given id is not/cannot be converted to a numerical value
|
* @throws will throw an error if the given id is not/cannot be converted to a numerical value
|
||||||
*/
|
*/
|
||||||
initialize:function(id) {
|
initialize(id) {
|
||||||
$assert(!isNaN(id), "id can not be null");
|
$assert(!isNaN(id), 'id can not be null');
|
||||||
this._id = id;
|
this._id = id;
|
||||||
this._position = null;
|
this._position = null;
|
||||||
this._order = null;
|
this._order = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @return id */
|
/** @return id */
|
||||||
getId:function() {
|
getId() {
|
||||||
return this._id;
|
return this._id;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @return order */
|
/** @return order */
|
||||||
getOrder: function() {
|
getOrder() {
|
||||||
return this._order;
|
return this._order;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @return position */
|
/** @return position */
|
||||||
getPosition: function() {
|
getPosition() {
|
||||||
return this._position;
|
return this._position;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {} value the order to set
|
* @param {} value the order to set
|
||||||
* @throws will throw an error if the given parameter is not/cannot be converted to a numerical
|
* @throws will throw an error if the given parameter is not/cannot be converted to a numerical
|
||||||
* value
|
* value
|
||||||
*/
|
*/
|
||||||
setOrder: function(value) {
|
setOrder(value) {
|
||||||
$assert(!isNaN(value), "value can not be null");
|
$assert(!isNaN(value), 'value can not be null');
|
||||||
this._order = value;
|
this._order = value;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @param {} value
|
/** @param {} value
|
||||||
* @throws will throw an error if the value is null or undefined*/
|
* @throws will throw an error if the value is null or undefined */
|
||||||
setPosition: function(value) {
|
setPosition(value) {
|
||||||
$assert(value, "value can not be null");
|
$assert(value, 'value can not be null');
|
||||||
this._position = value;
|
this._position = value;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @return {String} order and position */
|
/** @return {String} order and position */
|
||||||
toString: function() {
|
toString() {
|
||||||
return "[order:" + this.getOrder() + ", position: {" + this.getPosition().x + "," + this.getPosition().y + "}]";
|
return `[order:${this.getOrder()}, position: {${this.getPosition().x},${this.getPosition().y}}]`;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default ChangeEvent;
|
export default ChangeEvent;
|
||||||
|
@ -17,53 +17,53 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const ChildrenSorterStrategy = new Class(/** @lends ChildrenSorterStrategy */{
|
const ChildrenSorterStrategy = new Class(/** @lends ChildrenSorterStrategy */{
|
||||||
/**
|
/**
|
||||||
* @constructs
|
* @constructs
|
||||||
*/
|
*/
|
||||||
initialize:function() {
|
initialize() {
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
computeChildrenIdByHeights: function(treeSet, node) {
|
computeChildrenIdByHeights(treeSet, node) {
|
||||||
throw "Method must be implemented";
|
throw 'Method must be implemented';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
computeOffsets:function(treeSet, node) {
|
computeOffsets(treeSet, node) {
|
||||||
throw "Method must be implemented";
|
throw 'Method must be implemented';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
insert: function(treeSet, parent, child, order) {
|
insert(treeSet, parent, child, order) {
|
||||||
throw "Method must be implemented";
|
throw 'Method must be implemented';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
detach:function(treeSet, node) {
|
detach(treeSet, node) {
|
||||||
throw "Method must be implemented";
|
throw 'Method must be implemented';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
predict:function(treeSet, parent, node, position, free) {
|
predict(treeSet, parent, node, position, free) {
|
||||||
throw "Method must be implemented";
|
throw 'Method must be implemented';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
verify:function(treeSet, node) {
|
verify(treeSet, node) {
|
||||||
throw "Method must be implemented";
|
throw 'Method must be implemented';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
getChildDirection: function(treeSet, node) {
|
getChildDirection(treeSet, node) {
|
||||||
throw "Method must be implemented";
|
throw 'Method must be implemented';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
toString:function() {
|
toString() {
|
||||||
throw "Method must be implemented: print name";
|
throw 'Method must be implemented: print name';
|
||||||
}
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default ChildrenSorterStrategy
|
export default ChildrenSorterStrategy;
|
||||||
|
@ -18,13 +18,13 @@
|
|||||||
const Events = require('../Events').default;
|
const Events = require('../Events').default;
|
||||||
|
|
||||||
const EventBus = new Class(/** @lends EventBus */{
|
const EventBus = new Class(/** @lends EventBus */{
|
||||||
Implements: Events,
|
Implements: Events,
|
||||||
/**
|
/**
|
||||||
* @constructs
|
* @constructs
|
||||||
* @implements mindplot.Events
|
* @implements mindplot.Events
|
||||||
*/
|
*/
|
||||||
initialize: function() {
|
initialize() {
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -32,14 +32,14 @@ const EventBus = new Class(/** @lends EventBus */{
|
|||||||
* @enum {String}
|
* @enum {String}
|
||||||
*/
|
*/
|
||||||
EventBus.events = {
|
EventBus.events = {
|
||||||
NodeResizeEvent:'NodeResizeEvent',
|
NodeResizeEvent: 'NodeResizeEvent',
|
||||||
NodeMoveEvent:'NodeMoveEvent',
|
NodeMoveEvent: 'NodeMoveEvent',
|
||||||
NodeShrinkEvent:'NodeShrinkEvent',
|
NodeShrinkEvent: 'NodeShrinkEvent',
|
||||||
NodeConnectEvent:'NodeConnectEvent',
|
NodeConnectEvent: 'NodeConnectEvent',
|
||||||
NodeDisconnectEvent:'NodeDisconnectEvent',
|
NodeDisconnectEvent: 'NodeDisconnectEvent',
|
||||||
NodeAdded:'NodeAdded',
|
NodeAdded: 'NodeAdded',
|
||||||
NodeRemoved:'NodeRemoved',
|
NodeRemoved: 'NodeRemoved',
|
||||||
DoLayout:'DoLayout'
|
DoLayout: 'DoLayout',
|
||||||
};
|
};
|
||||||
|
|
||||||
/** instance */
|
/** instance */
|
||||||
|
@ -15,85 +15,84 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
const EventBus = require('./EventBus').default
|
const EventBus = require('./EventBus').default;
|
||||||
|
|
||||||
const EventBusDispatcher = new Class(/** @lends EventBusDispatcher */{
|
const EventBusDispatcher = new Class(/** @lends EventBusDispatcher */{
|
||||||
/**
|
/**
|
||||||
* @constructs
|
* @constructs
|
||||||
*/
|
*/
|
||||||
initialize:function() {
|
initialize() {
|
||||||
this.registerBusEvents();
|
this.registerBusEvents();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {mindplot.layout.LayoutManager} layoutManager
|
* @param {mindplot.layout.LayoutManager} layoutManager
|
||||||
*/
|
*/
|
||||||
setLayoutManager : function(layoutManager) {
|
setLayoutManager(layoutManager) {
|
||||||
this._layoutManager = layoutManager;
|
this._layoutManager = layoutManager;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* register bus events
|
* register bus events
|
||||||
*/
|
*/
|
||||||
registerBusEvents:function () {
|
registerBusEvents() {
|
||||||
EventBus.instance.addEvent(EventBus.events.NodeAdded, this._nodeAdded.bind(this));
|
EventBus.instance.addEvent(EventBus.events.NodeAdded, this._nodeAdded.bind(this));
|
||||||
EventBus.instance.addEvent(EventBus.events.NodeRemoved, this._nodeRemoved.bind(this));
|
EventBus.instance.addEvent(EventBus.events.NodeRemoved, this._nodeRemoved.bind(this));
|
||||||
EventBus.instance.addEvent(EventBus.events.NodeResizeEvent, this._nodeResizeEvent.bind(this));
|
EventBus.instance.addEvent(EventBus.events.NodeResizeEvent, this._nodeResizeEvent.bind(this));
|
||||||
EventBus.instance.addEvent(EventBus.events.NodeMoveEvent, this._nodeMoveEvent.bind(this));
|
EventBus.instance.addEvent(EventBus.events.NodeMoveEvent, this._nodeMoveEvent.bind(this));
|
||||||
EventBus.instance.addEvent(EventBus.events.NodeDisconnectEvent, this._nodeDisconnectEvent.bind(this));
|
EventBus.instance.addEvent(EventBus.events.NodeDisconnectEvent, this._nodeDisconnectEvent.bind(this));
|
||||||
EventBus.instance.addEvent(EventBus.events.NodeConnectEvent, this._nodeConnectEvent.bind(this));
|
EventBus.instance.addEvent(EventBus.events.NodeConnectEvent, this._nodeConnectEvent.bind(this));
|
||||||
EventBus.instance.addEvent(EventBus.events.NodeShrinkEvent, this._nodeShrinkEvent.bind(this));
|
EventBus.instance.addEvent(EventBus.events.NodeShrinkEvent, this._nodeShrinkEvent.bind(this));
|
||||||
EventBus.instance.addEvent(EventBus.events.DoLayout, this._doLayout.bind(this));
|
EventBus.instance.addEvent(EventBus.events.DoLayout, this._doLayout.bind(this));
|
||||||
},
|
},
|
||||||
|
|
||||||
_nodeResizeEvent: function(args) {
|
_nodeResizeEvent(args) {
|
||||||
this._layoutManager.updateNodeSize(args.node.getId(), args.size);
|
this._layoutManager.updateNodeSize(args.node.getId(), args.size);
|
||||||
},
|
},
|
||||||
|
|
||||||
_nodeMoveEvent: function(args) {
|
_nodeMoveEvent(args) {
|
||||||
this._layoutManager.moveNode(args.node.getId(), args.position);
|
this._layoutManager.moveNode(args.node.getId(), args.position);
|
||||||
},
|
},
|
||||||
|
|
||||||
_nodeDisconnectEvent: function(node) {
|
_nodeDisconnectEvent(node) {
|
||||||
this._layoutManager.disconnectNode(node.getId());
|
this._layoutManager.disconnectNode(node.getId());
|
||||||
},
|
},
|
||||||
|
|
||||||
_nodeConnectEvent: function(args) {
|
_nodeConnectEvent(args) {
|
||||||
this._layoutManager.connectNode(args.parentNode.getId(), args.childNode.getId(), args.childNode.getOrder());
|
this._layoutManager.connectNode(args.parentNode.getId(), args.childNode.getId(), args.childNode.getOrder());
|
||||||
|
},
|
||||||
|
|
||||||
},
|
_nodeShrinkEvent(node) {
|
||||||
|
this._layoutManager.updateShrinkState(node.getId(), node.areChildrenShrunken());
|
||||||
|
},
|
||||||
|
|
||||||
_nodeShrinkEvent: function(node) {
|
_nodeAdded(node) {
|
||||||
this._layoutManager.updateShrinkState(node.getId(), node.areChildrenShrunken());
|
// Central topic must not be added twice ...
|
||||||
},
|
if (node.getId() != 0) {
|
||||||
|
this._layoutManager.addNode(node.getId(), { width: 10, height: 10 }, node.getPosition());
|
||||||
_nodeAdded: function(node) {
|
this._layoutManager.updateShrinkState(node.getId(), node.areChildrenShrunken());
|
||||||
// Central topic must not be added twice ...
|
|
||||||
if (node.getId() != 0) {
|
|
||||||
this._layoutManager.addNode(node.getId(), {width:10,height:10}, node.getPosition());
|
|
||||||
this._layoutManager.updateShrinkState(node.getId(), node.areChildrenShrunken());
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_nodeRemoved: function(node) {
|
|
||||||
this._layoutManager.removeNode(node.getId());
|
|
||||||
},
|
|
||||||
|
|
||||||
_doLayout: function() {
|
|
||||||
// (function() {
|
|
||||||
this._layoutManager.layout(true);
|
|
||||||
// console.log("---------");
|
|
||||||
// this._layoutManager.dump();
|
|
||||||
// console.log("---------");
|
|
||||||
// console.log("---------");
|
|
||||||
// }).delay(0, this);
|
|
||||||
},
|
|
||||||
|
|
||||||
/** @return layout manager */
|
|
||||||
getLayoutManager: function() {
|
|
||||||
return this._layoutManager;
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_nodeRemoved(node) {
|
||||||
|
this._layoutManager.removeNode(node.getId());
|
||||||
|
},
|
||||||
|
|
||||||
|
_doLayout() {
|
||||||
|
// (function() {
|
||||||
|
this._layoutManager.layout(true);
|
||||||
|
// console.log("---------");
|
||||||
|
// this._layoutManager.dump();
|
||||||
|
// console.log("---------");
|
||||||
|
// console.log("---------");
|
||||||
|
// }).delay(0, this);
|
||||||
|
},
|
||||||
|
|
||||||
|
/** @return layout manager */
|
||||||
|
getLayoutManager() {
|
||||||
|
return this._layoutManager;
|
||||||
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default EventBusDispatcher
|
export default EventBusDispatcher;
|
||||||
|
@ -15,66 +15,63 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
const AbstractBasicSorter = require('./AbstractBasicSorter').default
|
const AbstractBasicSorter = require('./AbstractBasicSorter').default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class
|
* @class
|
||||||
* @extends mindplot.layout.AbstractBasicSorter
|
* @extends mindplot.layout.AbstractBasicSorter
|
||||||
*/
|
*/
|
||||||
const GridSorter = new Class(/** @lends GridSorter */{
|
const GridSorter = new Class(/** @lends GridSorter */{
|
||||||
Extends: AbstractBasicSorter,
|
Extends: AbstractBasicSorter,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {} treeSet
|
* @param {} treeSet
|
||||||
* @param {} node
|
* @param {} node
|
||||||
* @return offsets
|
* @return offsets
|
||||||
*/
|
*/
|
||||||
computeOffsets: function(treeSet, node) {
|
computeOffsets(treeSet, node) {
|
||||||
$assert(treeSet, "treeSet can no be null.");
|
$assert(treeSet, 'treeSet can no be null.');
|
||||||
$assert(node, "node can no be null.");
|
$assert(node, 'node can no be null.');
|
||||||
$assert("order can no be null.");
|
$assert('order can no be null.');
|
||||||
|
|
||||||
var children = this._getSortedChildren(treeSet, node);
|
const children = this._getSortedChildren(treeSet, node);
|
||||||
|
|
||||||
// Compute heights ...
|
// Compute heights ...
|
||||||
var me = this;
|
const me = this;
|
||||||
var heights = children.map(function(child) {
|
const heights = children.map((child) => ({
|
||||||
return {
|
id: child.getId(),
|
||||||
id: child.getId(),
|
height: me._computeChildrenHeight(treeSet, child),
|
||||||
height: me._computeChildrenHeight(treeSet, child)
|
}));
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Calculate the offsets ...
|
// Calculate the offsets ...
|
||||||
var result = {};
|
const result = {};
|
||||||
for (var i = 0; i < heights.length; i++) {
|
for (let i = 0; i < heights.length; i++) {
|
||||||
var even = i%2 == 0 ? 1 : -1;
|
const even = i % 2 == 0 ? 1 : -1;
|
||||||
|
|
||||||
var zeroHeight = i == 0 ? 0 : heights[0].height/2 * even;
|
const zeroHeight = i == 0 ? 0 : heights[0].height / 2 * even;
|
||||||
var middleHeight = 0;
|
let middleHeight = 0;
|
||||||
for (var j=i-2; j>0; j=j-2) {
|
for (let j = i - 2; j > 0; j -= 2) {
|
||||||
middleHeight += heights[j].height * even;
|
middleHeight += heights[j].height * even;
|
||||||
}
|
}
|
||||||
var finalHeight = i == 0 ? 0 : heights[i].height/2 * even;
|
const finalHeight = i == 0 ? 0 : heights[i].height / 2 * even;
|
||||||
|
|
||||||
var yOffset = zeroHeight + middleHeight +finalHeight;
|
const yOffset = zeroHeight + middleHeight + finalHeight;
|
||||||
var xOffset = node.getSize().width + GridSorter.GRID_HORIZONTAR_SIZE;
|
const xOffset = node.getSize().width + GridSorter.GRID_HORIZONTAR_SIZE;
|
||||||
|
|
||||||
$assert(!isNaN(xOffset), "xOffset can not be null");
|
$assert(!isNaN(xOffset), 'xOffset can not be null');
|
||||||
$assert(!isNaN(yOffset), "yOffset can not be null");
|
$assert(!isNaN(yOffset), 'yOffset can not be null');
|
||||||
|
|
||||||
result[heights[i].id] = {x:xOffset,y:yOffset};
|
result[heights[i].id] = { x: xOffset, y: yOffset };
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
}
|
/**
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {String} the print name of this class
|
* @return {String} the print name of this class
|
||||||
*/
|
*/
|
||||||
toString:function() {
|
toString() {
|
||||||
return "Grid Sorter";
|
return 'Grid Sorter';
|
||||||
}
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -21,9 +21,9 @@ const OriginalLayout = require('./OriginalLayout').default;
|
|||||||
const ChangeEvent = require('./ChangeEvent').default;
|
const ChangeEvent = require('./ChangeEvent').default;
|
||||||
|
|
||||||
const LayoutManager = new Class(
|
const LayoutManager = new Class(
|
||||||
/** @lends LayoutManager */ {
|
/** @lends LayoutManager */ {
|
||||||
Extends: Events,
|
Extends: Events,
|
||||||
/**
|
/**
|
||||||
* @constructs
|
* @constructs
|
||||||
* @extends mindplot.Events
|
* @extends mindplot.Events
|
||||||
* @param {} rootNodeId
|
* @param {} rootNodeId
|
||||||
@ -31,57 +31,57 @@ const LayoutManager = new Class(
|
|||||||
* @throws will throw an error if the root node id is null or undefined
|
* @throws will throw an error if the root node id is null or undefined
|
||||||
* @throws will throw an error if the root size is null
|
* @throws will throw an error if the root size is null
|
||||||
*/
|
*/
|
||||||
initialize: function (rootNodeId, rootSize) {
|
initialize(rootNodeId, rootSize) {
|
||||||
$assert($defined(rootNodeId), 'rootNodeId can not be null');
|
$assert($defined(rootNodeId), 'rootNodeId can not be null');
|
||||||
$assert(rootSize, 'rootSize can not be null');
|
$assert(rootSize, 'rootSize can not be null');
|
||||||
var position = position || { x: 0, y: 0 };
|
var position = position || { x: 0, y: 0 };
|
||||||
|
|
||||||
this._treeSet = new RootedTreeSet();
|
this._treeSet = new RootedTreeSet();
|
||||||
this._layout = new OriginalLayout(this._treeSet);
|
this._layout = new OriginalLayout(this._treeSet);
|
||||||
|
|
||||||
var rootNode = this._layout.createNode(rootNodeId, rootSize, position, 'root');
|
const rootNode = this._layout.createNode(rootNodeId, rootSize, position, 'root');
|
||||||
this._treeSet.setRoot(rootNode);
|
this._treeSet.setRoot(rootNode);
|
||||||
this._events = [];
|
this._events = [];
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param id
|
* @param id
|
||||||
* @param size
|
* @param size
|
||||||
* @throws will throw an error if id is null or undefined
|
* @throws will throw an error if id is null or undefined
|
||||||
*/
|
*/
|
||||||
updateNodeSize: function (id, size) {
|
updateNodeSize(id, size) {
|
||||||
$assert($defined(id), 'id can not be null');
|
$assert($defined(id), 'id can not be null');
|
||||||
|
|
||||||
var node = this._treeSet.find(id);
|
const node = this._treeSet.find(id);
|
||||||
node.setSize(size);
|
node.setSize(size);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param id
|
* @param id
|
||||||
* @param value
|
* @param value
|
||||||
* @throws will throw an error if id is null or undefined
|
* @throws will throw an error if id is null or undefined
|
||||||
* @throws will throw an error if value is null or undefined
|
* @throws will throw an error if value is null or undefined
|
||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
updateShrinkState: function (id, value) {
|
updateShrinkState(id, value) {
|
||||||
$assert($defined(id), 'id can not be null');
|
$assert($defined(id), 'id can not be null');
|
||||||
$assert($defined(value), 'value can not be null');
|
$assert($defined(value), 'value can not be null');
|
||||||
|
|
||||||
var node = this._treeSet.find(id);
|
const node = this._treeSet.find(id);
|
||||||
node.setShrunken(value);
|
node.setShrunken(value);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param id
|
* @param id
|
||||||
* @return {@link RootedTreeSet}.find(id)
|
* @return {@link RootedTreeSet}.find(id)
|
||||||
*/
|
*/
|
||||||
find: function (id) {
|
find(id) {
|
||||||
return this._treeSet.find(id);
|
return this._treeSet.find(id);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param id
|
* @param id
|
||||||
* @param position
|
* @param position
|
||||||
* @throws will throw an error if id is null or undefined
|
* @throws will throw an error if id is null or undefined
|
||||||
@ -89,20 +89,20 @@ const LayoutManager = new Class(
|
|||||||
* @throws will throw an error if the position's x property is null or undefined
|
* @throws will throw an error if the position's x property is null or undefined
|
||||||
* @throws will throw an error if the position's y property is null or undefined
|
* @throws will throw an error if the position's y property is null or undefined
|
||||||
*/
|
*/
|
||||||
moveNode: function (id, position) {
|
moveNode(id, position) {
|
||||||
$assert($defined(id), 'id cannot be null');
|
$assert($defined(id), 'id cannot be null');
|
||||||
$assert($defined(position), 'position cannot be null');
|
$assert($defined(position), 'position cannot be null');
|
||||||
$assert($defined(position.x), 'x can not be null');
|
$assert($defined(position.x), 'x can not be null');
|
||||||
$assert($defined(position.y), 'y can not be null');
|
$assert($defined(position.y), 'y can not be null');
|
||||||
|
|
||||||
var node = this._treeSet.find(id);
|
const node = this._treeSet.find(id);
|
||||||
// @Todo: this should not be here. This is broking the isolated node support...
|
// @Todo: this should not be here. This is broking the isolated node support...
|
||||||
// node.setFree(true);
|
// node.setFree(true);
|
||||||
// node.setFreeDisplacement({x:position.x - node.getPosition().x, y:position.y - node.getPosition().y});
|
// node.setFreeDisplacement({x:position.x - node.getPosition().x, y:position.y - node.getPosition().y});
|
||||||
node.setPosition(position);
|
node.setPosition(position);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param parentId
|
* @param parentId
|
||||||
* @param childId
|
* @param childId
|
||||||
* @param order
|
* @param order
|
||||||
@ -111,65 +111,65 @@ const LayoutManager = new Class(
|
|||||||
* @throws will throw an error if order is null or undefined
|
* @throws will throw an error if order is null or undefined
|
||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
connectNode: function (parentId, childId, order) {
|
connectNode(parentId, childId, order) {
|
||||||
$assert($defined(parentId), 'parentId cannot be null');
|
$assert($defined(parentId), 'parentId cannot be null');
|
||||||
$assert($defined(childId), 'childId cannot be null');
|
$assert($defined(childId), 'childId cannot be null');
|
||||||
$assert($defined(order), 'order cannot be null');
|
$assert($defined(order), 'order cannot be null');
|
||||||
|
|
||||||
this._layout.connectNode(parentId, childId, order);
|
this._layout.connectNode(parentId, childId, order);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param id
|
* @param id
|
||||||
* @throws will throw an error if id is null or undefined
|
* @throws will throw an error if id is null or undefined
|
||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
disconnectNode: function (id) {
|
disconnectNode(id) {
|
||||||
$assert($defined(id), 'id can not be null');
|
$assert($defined(id), 'id can not be null');
|
||||||
this._layout.disconnectNode(id);
|
this._layout.disconnectNode(id);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param id
|
* @param id
|
||||||
* @param size
|
* @param size
|
||||||
* @param position
|
* @param position
|
||||||
* @throws will throw an error if id is null or undefined
|
* @throws will throw an error if id is null or undefined
|
||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
addNode: function (id, size, position) {
|
addNode(id, size, position) {
|
||||||
$assert($defined(id), 'id can not be null');
|
$assert($defined(id), 'id can not be null');
|
||||||
var result = this._layout.createNode(id, size, position, 'topic');
|
const result = this._layout.createNode(id, size, position, 'topic');
|
||||||
this._treeSet.add(result);
|
this._treeSet.add(result);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* removes a node and its connection to parent if existing
|
* removes a node and its connection to parent if existing
|
||||||
* @param id
|
* @param id
|
||||||
* @throws will throw an error if id is null or undefined
|
* @throws will throw an error if id is null or undefined
|
||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
removeNode: function (id) {
|
removeNode(id) {
|
||||||
$assert($defined(id), 'id can not be null');
|
$assert($defined(id), 'id can not be null');
|
||||||
var node = this._treeSet.find(id);
|
const node = this._treeSet.find(id);
|
||||||
|
|
||||||
// Is It connected ?
|
// Is It connected ?
|
||||||
if (this._treeSet.getParent(node)) {
|
if (this._treeSet.getParent(node)) {
|
||||||
this.disconnectNode(id);
|
this.disconnectNode(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the all the branch ...
|
// Remove the all the branch ...
|
||||||
this._treeSet.remove(id);
|
this._treeSet.remove(id);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Number} parentId
|
* @param {Number} parentId
|
||||||
* @param {Number=} nodeId
|
* @param {Number=} nodeId
|
||||||
* @param {String=} position the position to use as mindplot.layout.Node.properties position
|
* @param {String=} position the position to use as mindplot.layout.Node.properties position
|
||||||
@ -177,109 +177,107 @@ const LayoutManager = new Class(
|
|||||||
* @param {Boolean=} free true specifies free node positioning
|
* @param {Boolean=} free true specifies free node positioning
|
||||||
* @throws will throw an error if parentId is null or undefined
|
* @throws will throw an error if parentId is null or undefined
|
||||||
*/
|
*/
|
||||||
predict: function (parentId, nodeId, position, free) {
|
predict(parentId, nodeId, position, free) {
|
||||||
$assert($defined(parentId), 'parentId can not be null');
|
$assert($defined(parentId), 'parentId can not be null');
|
||||||
|
|
||||||
var parent = this._treeSet.find(parentId);
|
const parent = this._treeSet.find(parentId);
|
||||||
var node = nodeId ? this._treeSet.find(nodeId) : null;
|
const node = nodeId ? this._treeSet.find(nodeId) : null;
|
||||||
var sorter = parent.getSorter();
|
const sorter = parent.getSorter();
|
||||||
|
|
||||||
var result = sorter.predict(this._treeSet, parent, node, position, free);
|
const result = sorter.predict(this._treeSet, parent, node, position, free);
|
||||||
return { order: result[0], position: result[1] };
|
return { order: result[0], position: result[1] };
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* logs dump to console
|
* logs dump to console
|
||||||
*/
|
*/
|
||||||
dump: function () {
|
dump() {
|
||||||
console.log(this._treeSet.dump());
|
console.log(this._treeSet.dump());
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param containerId
|
* @param containerId
|
||||||
* @param {width:Number, height:Number} size
|
* @param {width:Number, height:Number} size
|
||||||
* @throws will throw an error if containerId is null or undefined
|
* @throws will throw an error if containerId is null or undefined
|
||||||
* @return canvas
|
* @return canvas
|
||||||
*/
|
*/
|
||||||
plot: function (containerId, size) {
|
plot(containerId, size) {
|
||||||
$assert(containerId, 'containerId cannot be null');
|
$assert(containerId, 'containerId cannot be null');
|
||||||
size = size || { width: 200, height: 200 };
|
size = size || { width: 200, height: 200 };
|
||||||
var squaresize = 10;
|
const squaresize = 10;
|
||||||
var canvas = Raphael(containerId, size.width, size.height);
|
const canvas = Raphael(containerId, size.width, size.height);
|
||||||
canvas.drawGrid(
|
canvas.drawGrid(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
size.width,
|
size.width,
|
||||||
size.height,
|
size.height,
|
||||||
size.width / squaresize,
|
size.width / squaresize,
|
||||||
size.height / squaresize
|
size.height / squaresize,
|
||||||
);
|
);
|
||||||
this._treeSet.plot(canvas);
|
this._treeSet.plot(canvas);
|
||||||
|
|
||||||
return canvas;
|
return canvas;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* initializes the layout to be updated
|
* initializes the layout to be updated
|
||||||
* @param fireEvents
|
* @param fireEvents
|
||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
layout: function (fireEvents) {
|
layout(fireEvents) {
|
||||||
// File repositioning ...
|
// File repositioning ...
|
||||||
this._layout.layout();
|
this._layout.layout();
|
||||||
|
|
||||||
// Collect changes ...
|
// Collect changes ...
|
||||||
this._collectChanges();
|
this._collectChanges();
|
||||||
|
|
||||||
if ($(fireEvents).length > 0 || fireEvents) {
|
if ($(fireEvents).length > 0 || fireEvents) {
|
||||||
this._flushEvents();
|
this._flushEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
_flushEvents() {
|
||||||
|
_.each(
|
||||||
|
this._events,
|
||||||
|
function (event) {
|
||||||
|
this.fireEvent('change', event);
|
||||||
|
},
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
this._events = [];
|
||||||
|
},
|
||||||
|
|
||||||
|
_collectChanges(nodes) {
|
||||||
|
if (!nodes) nodes = this._treeSet.getTreeRoots();
|
||||||
|
|
||||||
|
_.each(
|
||||||
|
nodes,
|
||||||
|
function (node) {
|
||||||
|
if (node.hasOrderChanged() || node.hasPositionChanged()) {
|
||||||
|
// Find or create a event ...
|
||||||
|
const id = node.getId();
|
||||||
|
let event = this._events.some((event) => event.id == id);
|
||||||
|
if (!event) {
|
||||||
|
event = new ChangeEvent(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
// Update nodes ...
|
||||||
|
event.setOrder(node.getOrder());
|
||||||
|
event.setPosition(node.getPosition());
|
||||||
|
|
||||||
|
node.resetPositionState();
|
||||||
|
node.resetOrderState();
|
||||||
|
node.resetFreeState();
|
||||||
|
this._events.push(event);
|
||||||
|
}
|
||||||
|
this._collectChanges(this._treeSet.getChildren(node));
|
||||||
},
|
},
|
||||||
|
this,
|
||||||
_flushEvents: function () {
|
);
|
||||||
_.each(
|
},
|
||||||
this._events,
|
},
|
||||||
function (event) {
|
|
||||||
this.fireEvent('change', event);
|
|
||||||
},
|
|
||||||
this
|
|
||||||
);
|
|
||||||
this._events = [];
|
|
||||||
},
|
|
||||||
|
|
||||||
_collectChanges: function (nodes) {
|
|
||||||
if (!nodes) nodes = this._treeSet.getTreeRoots();
|
|
||||||
|
|
||||||
_.each(
|
|
||||||
nodes,
|
|
||||||
function (node) {
|
|
||||||
if (node.hasOrderChanged() || node.hasPositionChanged()) {
|
|
||||||
// Find or create a event ...
|
|
||||||
var id = node.getId();
|
|
||||||
var event = this._events.some(function (event) {
|
|
||||||
return event.id == id;
|
|
||||||
});
|
|
||||||
if (!event) {
|
|
||||||
event = new ChangeEvent(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update nodes ...
|
|
||||||
event.setOrder(node.getOrder());
|
|
||||||
event.setPosition(node.getPosition());
|
|
||||||
|
|
||||||
node.resetPositionState();
|
|
||||||
node.resetOrderState();
|
|
||||||
node.resetFreeState();
|
|
||||||
this._events.push(event);
|
|
||||||
}
|
|
||||||
this._collectChanges(this._treeSet.getChildren(node));
|
|
||||||
},
|
|
||||||
this
|
|
||||||
);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
export default LayoutManager;
|
export default LayoutManager;
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const Node = new Class(
|
const Node = new Class(
|
||||||
/** @lends Node */ {
|
/** @lends Node */ {
|
||||||
/**
|
/**
|
||||||
* @constructs
|
* @constructs
|
||||||
* @param id
|
* @param id
|
||||||
* @param size
|
* @param size
|
||||||
@ -29,221 +29,220 @@ const Node = new Class(
|
|||||||
* @throws will throw an error if position is null or undefined
|
* @throws will throw an error if position is null or undefined
|
||||||
* @throws will throw an error if sorter is null or undefined
|
* @throws will throw an error if sorter is null or undefined
|
||||||
*/
|
*/
|
||||||
initialize: function (id, size, position, sorter) {
|
initialize(id, size, position, sorter) {
|
||||||
$assert(typeof id === 'number' && isFinite(id), 'id can not be null');
|
$assert(typeof id === 'number' && isFinite(id), 'id can not be null');
|
||||||
$assert(size, 'size can not be null');
|
$assert(size, 'size can not be null');
|
||||||
$assert(position, 'position can not be null');
|
$assert(position, 'position can not be null');
|
||||||
$assert(sorter, 'sorter can not be null');
|
$assert(sorter, 'sorter can not be null');
|
||||||
|
|
||||||
this._id = id;
|
this._id = id;
|
||||||
this._sorter = sorter;
|
this._sorter = sorter;
|
||||||
this._properties = {};
|
this._properties = {};
|
||||||
|
|
||||||
this.setSize(size);
|
this.setSize(size);
|
||||||
this.setPosition(position);
|
this.setPosition(position);
|
||||||
this.setShrunken(false);
|
this.setShrunken(false);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getId: function () {
|
getId() {
|
||||||
return this._id;
|
return this._id;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setFree: function (value) {
|
setFree(value) {
|
||||||
this._setProperty('free', value);
|
this._setProperty('free', value);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
isFree: function () {
|
isFree() {
|
||||||
return this._getProperty('free');
|
return this._getProperty('free');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
hasFreeChanged: function () {
|
hasFreeChanged() {
|
||||||
return this._isPropertyChanged('free');
|
return this._isPropertyChanged('free');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
hasFreeDisplacementChanged: function () {
|
hasFreeDisplacementChanged() {
|
||||||
return this._isPropertyChanged('freeDisplacement');
|
return this._isPropertyChanged('freeDisplacement');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setShrunken: function (value) {
|
setShrunken(value) {
|
||||||
this._setProperty('shrink', value);
|
this._setProperty('shrink', value);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
areChildrenShrunken: function () {
|
areChildrenShrunken() {
|
||||||
return this._getProperty('shrink');
|
return this._getProperty('shrink');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setOrder: function (order) {
|
setOrder(order) {
|
||||||
$assert(
|
$assert(
|
||||||
typeof order === 'number' && isFinite(order),
|
typeof order === 'number' && isFinite(order),
|
||||||
'Order can not be null. Value:' + order
|
`Order can not be null. Value:${order}`,
|
||||||
);
|
);
|
||||||
this._setProperty('order', order);
|
this._setProperty('order', order);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
resetPositionState: function () {
|
resetPositionState() {
|
||||||
var prop = this._properties['position'];
|
const prop = this._properties.position;
|
||||||
if (prop) {
|
if (prop) {
|
||||||
prop.hasChanged = false;
|
prop.hasChanged = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
resetOrderState: function () {
|
resetOrderState() {
|
||||||
var prop = this._properties['order'];
|
const prop = this._properties.order;
|
||||||
if (prop) {
|
if (prop) {
|
||||||
prop.hasChanged = false;
|
prop.hasChanged = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
resetFreeState: function () {
|
resetFreeState() {
|
||||||
var prop = this._properties['freeDisplacement'];
|
const prop = this._properties.freeDisplacement;
|
||||||
if (prop) {
|
if (prop) {
|
||||||
prop.hasChanged = false;
|
prop.hasChanged = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getOrder: function () {
|
getOrder() {
|
||||||
return this._getProperty('order');
|
return this._getProperty('order');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
hasOrderChanged: function () {
|
hasOrderChanged() {
|
||||||
return this._isPropertyChanged('order');
|
return this._isPropertyChanged('order');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
hasPositionChanged: function () {
|
hasPositionChanged() {
|
||||||
return this._isPropertyChanged('position');
|
return this._isPropertyChanged('position');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
hasSizeChanged: function () {
|
hasSizeChanged() {
|
||||||
return this._isPropertyChanged('size');
|
return this._isPropertyChanged('size');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getPosition: function () {
|
getPosition() {
|
||||||
return this._getProperty('position');
|
return this._getProperty('position');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setSize: function (size) {
|
setSize(size) {
|
||||||
$assert($defined(size), 'Size can not be null');
|
$assert($defined(size), 'Size can not be null');
|
||||||
this._setProperty('size', Object.clone(size));
|
this._setProperty('size', Object.clone(size));
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getSize: function () {
|
getSize() {
|
||||||
return this._getProperty('size');
|
return this._getProperty('size');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setFreeDisplacement: function (displacement) {
|
setFreeDisplacement(displacement) {
|
||||||
$assert($defined(displacement), 'Position can not be null');
|
$assert($defined(displacement), 'Position can not be null');
|
||||||
$assert($defined(displacement.x), 'x can not be null');
|
$assert($defined(displacement.x), 'x can not be null');
|
||||||
$assert($defined(displacement.y), 'y can not be null');
|
$assert($defined(displacement.y), 'y can not be null');
|
||||||
var oldDisplacement = this.getFreeDisplacement();
|
const oldDisplacement = this.getFreeDisplacement();
|
||||||
var newDisplacement = {
|
const newDisplacement = {
|
||||||
x: oldDisplacement.x + displacement.x,
|
x: oldDisplacement.x + displacement.x,
|
||||||
y: oldDisplacement.y + displacement.y,
|
y: oldDisplacement.y + displacement.y,
|
||||||
};
|
};
|
||||||
|
|
||||||
this._setProperty('freeDisplacement', Object.clone(newDisplacement));
|
this._setProperty('freeDisplacement', Object.clone(newDisplacement));
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
resetFreeDisplacement: function () {
|
resetFreeDisplacement() {
|
||||||
this._setProperty('freeDisplacement', { x: 0, y: 0 });
|
this._setProperty('freeDisplacement', { x: 0, y: 0 });
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getFreeDisplacement: function () {
|
getFreeDisplacement() {
|
||||||
var freeDisplacement = this._getProperty('freeDisplacement');
|
const freeDisplacement = this._getProperty('freeDisplacement');
|
||||||
return freeDisplacement || { x: 0, y: 0 };
|
return freeDisplacement || { x: 0, y: 0 };
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setPosition: function (position) {
|
setPosition(position) {
|
||||||
$assert($defined(position), 'Position can not be null');
|
$assert($defined(position), 'Position can not be null');
|
||||||
$assert($defined(position.x), 'x can not be null');
|
$assert($defined(position.x), 'x can not be null');
|
||||||
$assert($defined(position.y), 'y can not be null');
|
$assert($defined(position.y), 'y can not be null');
|
||||||
|
|
||||||
// This is a performance improvement to avoid movements that really could be avoided.
|
// This is a performance improvement to avoid movements that really could be avoided.
|
||||||
var currentPos = this.getPosition();
|
const currentPos = this.getPosition();
|
||||||
if (
|
if (
|
||||||
currentPos == null ||
|
currentPos == null
|
||||||
Math.abs(currentPos.x - position.x) > 2 ||
|
|| Math.abs(currentPos.x - position.x) > 2
|
||||||
Math.abs(currentPos.y - position.y) > 2
|
|| Math.abs(currentPos.y - position.y) > 2
|
||||||
)
|
) this._setProperty('position', position);
|
||||||
this._setProperty('position', position);
|
},
|
||||||
},
|
|
||||||
|
|
||||||
_setProperty: function (key, value) {
|
_setProperty(key, value) {
|
||||||
var prop = this._properties[key];
|
let prop = this._properties[key];
|
||||||
if (!prop) {
|
if (!prop) {
|
||||||
prop = {
|
prop = {
|
||||||
hasChanged: false,
|
hasChanged: false,
|
||||||
value: null,
|
value: null,
|
||||||
oldValue: null,
|
oldValue: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only update if the property has changed ...
|
// Only update if the property has changed ...
|
||||||
if (JSON.stringify(prop.value) != JSON.stringify(value)) {
|
if (JSON.stringify(prop.value) != JSON.stringify(value)) {
|
||||||
prop.oldValue = prop.value;
|
prop.oldValue = prop.value;
|
||||||
prop.value = value;
|
prop.value = value;
|
||||||
prop.hasChanged = true;
|
prop.hasChanged = true;
|
||||||
}
|
}
|
||||||
this._properties[key] = prop;
|
this._properties[key] = prop;
|
||||||
},
|
},
|
||||||
|
|
||||||
_getProperty: function (key) {
|
_getProperty(key) {
|
||||||
var prop = this._properties[key];
|
const prop = this._properties[key];
|
||||||
return $defined(prop) ? prop.value : null;
|
return $defined(prop) ? prop.value : null;
|
||||||
},
|
},
|
||||||
|
|
||||||
_isPropertyChanged: function (key) {
|
_isPropertyChanged(key) {
|
||||||
var prop = this._properties[key];
|
const prop = this._properties[key];
|
||||||
return prop ? prop.hasChanged : false;
|
return prop ? prop.hasChanged : false;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getSorter: function () {
|
getSorter() {
|
||||||
return this._sorter;
|
return this._sorter;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @return {String} returns id, order, position, size and shrink information*/
|
/** @return {String} returns id, order, position, size and shrink information */
|
||||||
toString: function () {
|
toString() {
|
||||||
return (
|
return (
|
||||||
'[id:' +
|
`[id:${
|
||||||
this.getId() +
|
this.getId()
|
||||||
', order:' +
|
}, order:${
|
||||||
this.getOrder() +
|
this.getOrder()
|
||||||
', position: {' +
|
}, position: {${
|
||||||
this.getPosition().x +
|
this.getPosition().x
|
||||||
',' +
|
},${
|
||||||
this.getPosition().y +
|
this.getPosition().y
|
||||||
'}, size: {' +
|
}}, size: {${
|
||||||
this.getSize().width +
|
this.getSize().width
|
||||||
',' +
|
},${
|
||||||
this.getSize().height +
|
this.getSize().height
|
||||||
'}, shrink:' +
|
}}, shrink:${
|
||||||
this.areChildrenShrunken() +
|
this.areChildrenShrunken()
|
||||||
']'
|
}]`
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
export default Node;
|
export default Node;
|
||||||
|
@ -21,267 +21,259 @@ const SymmetricSorter = require('./SymmetricSorter').default;
|
|||||||
const BalancedSorter = require('./BalancedSorter').default;
|
const BalancedSorter = require('./BalancedSorter').default;
|
||||||
|
|
||||||
const OriginalLayout = new Class(
|
const OriginalLayout = new Class(
|
||||||
/** @lends OriginalLayout */ {
|
/** @lends OriginalLayout */ {
|
||||||
/**
|
/**
|
||||||
* @constructs
|
* @constructs
|
||||||
* @param treeSet
|
* @param treeSet
|
||||||
*/
|
*/
|
||||||
initialize: function (treeSet) {
|
initialize(treeSet) {
|
||||||
this._treeSet = treeSet;
|
this._treeSet = treeSet;
|
||||||
|
},
|
||||||
|
|
||||||
|
/** */
|
||||||
|
createNode(id, size, position, type) {
|
||||||
|
$assert($defined(id), 'id can not be null');
|
||||||
|
$assert(size, 'size can not be null');
|
||||||
|
$assert(position, 'position can not be null');
|
||||||
|
$assert(type, 'type can not be null');
|
||||||
|
|
||||||
|
const strategy = type === 'root' ? OriginalLayout.BALANCED_SORTER : OriginalLayout.SYMMETRIC_SORTER;
|
||||||
|
return new Node(id, size, position, strategy);
|
||||||
|
},
|
||||||
|
|
||||||
|
/** */
|
||||||
|
connectNode(parentId, childId, order) {
|
||||||
|
const parent = this._treeSet.find(parentId);
|
||||||
|
const child = this._treeSet.find(childId);
|
||||||
|
|
||||||
|
// Insert the new node ...
|
||||||
|
const sorter = parent.getSorter();
|
||||||
|
sorter.insert(this._treeSet, parent, child, order);
|
||||||
|
|
||||||
|
// Connect the new node ...
|
||||||
|
this._treeSet.connect(parentId, childId);
|
||||||
|
|
||||||
|
// Fire a basic validation ...
|
||||||
|
sorter.verify(this._treeSet, parent);
|
||||||
|
},
|
||||||
|
|
||||||
|
/** */
|
||||||
|
disconnectNode(nodeId) {
|
||||||
|
const node = this._treeSet.find(nodeId);
|
||||||
|
const parent = this._treeSet.getParent(node);
|
||||||
|
$assert(parent, 'Node already disconnected');
|
||||||
|
|
||||||
|
// Make it fixed
|
||||||
|
node.setFree(false);
|
||||||
|
node.resetFreeDisplacement();
|
||||||
|
|
||||||
|
// Remove from children list.
|
||||||
|
const sorter = parent.getSorter();
|
||||||
|
sorter.detach(this._treeSet, node);
|
||||||
|
|
||||||
|
// Disconnect the new node ...
|
||||||
|
this._treeSet.disconnect(nodeId);
|
||||||
|
|
||||||
|
// Fire a basic validation ...
|
||||||
|
parent.getSorter().verify(this._treeSet, parent);
|
||||||
|
},
|
||||||
|
|
||||||
|
/** */
|
||||||
|
layout() {
|
||||||
|
const roots = this._treeSet.getTreeRoots();
|
||||||
|
_.each(
|
||||||
|
roots,
|
||||||
|
function (node) {
|
||||||
|
// Calculate all node heights ...
|
||||||
|
const sorter = node.getSorter();
|
||||||
|
|
||||||
|
const heightById = sorter.computeChildrenIdByHeights(this._treeSet, node);
|
||||||
|
|
||||||
|
this._layoutChildren(node, heightById);
|
||||||
|
|
||||||
|
this._fixOverlapping(node, heightById);
|
||||||
},
|
},
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
/** */
|
_layoutChildren(node, heightById) {
|
||||||
createNode: function (id, size, position, type) {
|
const nodeId = node.getId();
|
||||||
$assert($defined(id), 'id can not be null');
|
const children = this._treeSet.getChildren(node);
|
||||||
$assert(size, 'size can not be null');
|
const parent = this._treeSet.getParent(node);
|
||||||
$assert(position, 'position can not be null');
|
const childrenOrderMoved = children.some((child) => child.hasOrderChanged());
|
||||||
$assert(type, 'type can not be null');
|
const childrenSizeChanged = children.some((child) => child.hasSizeChanged());
|
||||||
|
|
||||||
var strategy =
|
// If ether any of the nodes has been changed of position or the height of the children is not
|
||||||
type === 'root' ? OriginalLayout.BALANCED_SORTER : OriginalLayout.SYMMETRIC_SORTER;
|
// the same, children nodes must be repositioned ....
|
||||||
return new Node(id, size, position, strategy);
|
const newBranchHeight = heightById[nodeId];
|
||||||
},
|
|
||||||
|
|
||||||
/** */
|
const parentHeightChanged = $defined(parent) ? parent._heightChanged : false;
|
||||||
connectNode: function (parentId, childId, order) {
|
const heightChanged = node._branchHeight != newBranchHeight;
|
||||||
var parent = this._treeSet.find(parentId);
|
node._heightChanged = heightChanged || parentHeightChanged;
|
||||||
var child = this._treeSet.find(childId);
|
|
||||||
|
|
||||||
// Insert the new node ...
|
if (childrenOrderMoved || childrenSizeChanged || heightChanged || parentHeightChanged) {
|
||||||
var sorter = parent.getSorter();
|
const sorter = node.getSorter();
|
||||||
sorter.insert(this._treeSet, parent, child, order);
|
const offsetById = sorter.computeOffsets(this._treeSet, node);
|
||||||
|
const parentPosition = node.getPosition();
|
||||||
|
const me = this;
|
||||||
|
_.each(children, (child) => {
|
||||||
|
const offset = offsetById[child.getId()];
|
||||||
|
|
||||||
// Connect the new node ...
|
const childFreeDisplacement = child.getFreeDisplacement();
|
||||||
this._treeSet.connect(parentId, childId);
|
const direction = node.getSorter().getChildDirection(me._treeSet, child);
|
||||||
|
|
||||||
// Fire a basic validation ...
|
if (
|
||||||
sorter.verify(this._treeSet, parent);
|
(direction > 0 && childFreeDisplacement.x < 0)
|
||||||
},
|
|| (direction < 0 && childFreeDisplacement.x > 0)
|
||||||
|
) {
|
||||||
/** */
|
child.resetFreeDisplacement();
|
||||||
disconnectNode: function (nodeId) {
|
child.setFreeDisplacement({
|
||||||
var node = this._treeSet.find(nodeId);
|
x: -childFreeDisplacement.x,
|
||||||
var parent = this._treeSet.getParent(node);
|
y: childFreeDisplacement.y,
|
||||||
$assert(parent, 'Node already disconnected');
|
|
||||||
|
|
||||||
// Make it fixed
|
|
||||||
node.setFree(false);
|
|
||||||
node.resetFreeDisplacement();
|
|
||||||
|
|
||||||
// Remove from children list.
|
|
||||||
var sorter = parent.getSorter();
|
|
||||||
sorter.detach(this._treeSet, node);
|
|
||||||
|
|
||||||
// Disconnect the new node ...
|
|
||||||
this._treeSet.disconnect(nodeId);
|
|
||||||
|
|
||||||
// Fire a basic validation ...
|
|
||||||
parent.getSorter().verify(this._treeSet, parent);
|
|
||||||
},
|
|
||||||
|
|
||||||
/** */
|
|
||||||
layout: function () {
|
|
||||||
var roots = this._treeSet.getTreeRoots();
|
|
||||||
_.each(
|
|
||||||
roots,
|
|
||||||
function (node) {
|
|
||||||
// Calculate all node heights ...
|
|
||||||
var sorter = node.getSorter();
|
|
||||||
|
|
||||||
var heightById = sorter.computeChildrenIdByHeights(this._treeSet, node);
|
|
||||||
|
|
||||||
this._layoutChildren(node, heightById);
|
|
||||||
|
|
||||||
this._fixOverlapping(node, heightById);
|
|
||||||
},
|
|
||||||
this
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
_layoutChildren: function (node, heightById) {
|
|
||||||
var nodeId = node.getId();
|
|
||||||
var children = this._treeSet.getChildren(node);
|
|
||||||
var parent = this._treeSet.getParent(node);
|
|
||||||
var childrenOrderMoved = children.some(function (child) {
|
|
||||||
return child.hasOrderChanged();
|
|
||||||
});
|
|
||||||
var childrenSizeChanged = children.some(function (child) {
|
|
||||||
return child.hasSizeChanged();
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// If ether any of the nodes has been changed of position or the height of the children is not
|
offset.x += child.getFreeDisplacement().x;
|
||||||
// the same, children nodes must be repositioned ....
|
offset.y += child.getFreeDisplacement().y;
|
||||||
var newBranchHeight = heightById[nodeId];
|
|
||||||
|
|
||||||
var parentHeightChanged = $defined(parent) ? parent._heightChanged : false;
|
const parentX = parentPosition.x;
|
||||||
var heightChanged = node._branchHeight != newBranchHeight;
|
const parentY = parentPosition.y;
|
||||||
node._heightChanged = heightChanged || parentHeightChanged;
|
|
||||||
|
|
||||||
if (childrenOrderMoved || childrenSizeChanged || heightChanged || parentHeightChanged) {
|
const newPos = {
|
||||||
var sorter = node.getSorter();
|
x: parentX + offset.x,
|
||||||
var offsetById = sorter.computeOffsets(this._treeSet, node);
|
y: parentY + offset.y + me._calculateAlignOffset(node, child, heightById),
|
||||||
var parentPosition = node.getPosition();
|
};
|
||||||
var me = this;
|
me._treeSet.updateBranchPosition(child, newPos);
|
||||||
_.each(children, function (child) {
|
});
|
||||||
var offset = offsetById[child.getId()];
|
|
||||||
|
|
||||||
var childFreeDisplacement = child.getFreeDisplacement();
|
node._branchHeight = newBranchHeight;
|
||||||
var direction = node.getSorter().getChildDirection(me._treeSet, child);
|
}
|
||||||
|
|
||||||
if (
|
// Continue reordering the children nodes ...
|
||||||
(direction > 0 && childFreeDisplacement.x < 0) ||
|
_.each(
|
||||||
(direction < 0 && childFreeDisplacement.x > 0)
|
children,
|
||||||
) {
|
function (child) {
|
||||||
child.resetFreeDisplacement();
|
this._layoutChildren(child, heightById);
|
||||||
child.setFreeDisplacement({
|
|
||||||
x: -childFreeDisplacement.x,
|
|
||||||
y: childFreeDisplacement.y,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
offset.x += child.getFreeDisplacement().x;
|
|
||||||
offset.y += child.getFreeDisplacement().y;
|
|
||||||
|
|
||||||
var parentX = parentPosition.x;
|
|
||||||
var parentY = parentPosition.y;
|
|
||||||
|
|
||||||
var newPos = {
|
|
||||||
x: parentX + offset.x,
|
|
||||||
y: parentY + offset.y + me._calculateAlignOffset(node, child, heightById),
|
|
||||||
};
|
|
||||||
me._treeSet.updateBranchPosition(child, newPos);
|
|
||||||
});
|
|
||||||
|
|
||||||
node._branchHeight = newBranchHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Continue reordering the children nodes ...
|
|
||||||
_.each(
|
|
||||||
children,
|
|
||||||
function (child) {
|
|
||||||
this._layoutChildren(child, heightById);
|
|
||||||
},
|
|
||||||
this
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
_calculateAlignOffset: function (node, child, heightById) {
|
_calculateAlignOffset(node, child, heightById) {
|
||||||
if (child.isFree()) {
|
if (child.isFree()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
var offset = 0;
|
let offset = 0;
|
||||||
|
|
||||||
var nodeHeight = node.getSize().height;
|
const nodeHeight = node.getSize().height;
|
||||||
var childHeight = child.getSize().height;
|
const childHeight = child.getSize().height;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
this._treeSet.isStartOfSubBranch(child) &&
|
this._treeSet.isStartOfSubBranch(child)
|
||||||
this._branchIsTaller(child, heightById)
|
&& this._branchIsTaller(child, heightById)
|
||||||
) {
|
) {
|
||||||
if (this._treeSet.hasSinglePathToSingleLeaf(child)) {
|
if (this._treeSet.hasSinglePathToSingleLeaf(child)) {
|
||||||
offset =
|
offset = heightById[child.getId()] / 2
|
||||||
heightById[child.getId()] / 2 -
|
- (childHeight + child.getSorter()._getVerticalPadding() * 2) / 2;
|
||||||
(childHeight + child.getSorter()._getVerticalPadding() * 2) / 2;
|
} else {
|
||||||
} else {
|
offset = this._treeSet.isLeaf(child) ? 0 : -(childHeight - nodeHeight) / 2;
|
||||||
offset = this._treeSet.isLeaf(child) ? 0 : -(childHeight - nodeHeight) / 2;
|
}
|
||||||
}
|
} else if (nodeHeight > childHeight) {
|
||||||
} else if (nodeHeight > childHeight) {
|
if (this._treeSet.getSiblings(child).length > 0) {
|
||||||
if (this._treeSet.getSiblings(child).length > 0) {
|
offset = 0;
|
||||||
offset = 0;
|
} else {
|
||||||
} else {
|
offset = nodeHeight / 2 - childHeight / 2;
|
||||||
offset = nodeHeight / 2 - childHeight / 2;
|
}
|
||||||
}
|
} else if (childHeight > nodeHeight) {
|
||||||
} else if (childHeight > nodeHeight) {
|
if (this._treeSet.getSiblings(child).length > 0) {
|
||||||
if (this._treeSet.getSiblings(child).length > 0) {
|
offset = 0;
|
||||||
offset = 0;
|
} else {
|
||||||
} else {
|
offset = -(childHeight / 2 - nodeHeight / 2);
|
||||||
offset = -(childHeight / 2 - nodeHeight / 2);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return offset;
|
return offset;
|
||||||
|
},
|
||||||
|
|
||||||
|
_branchIsTaller(node, heightById) {
|
||||||
|
return (
|
||||||
|
heightById[node.getId()]
|
||||||
|
> node.getSize().height + node.getSorter()._getVerticalPadding() * 2
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
_fixOverlapping(node, heightById) {
|
||||||
|
const children = this._treeSet.getChildren(node);
|
||||||
|
|
||||||
|
if (node.isFree()) {
|
||||||
|
this._shiftBranches(node, heightById);
|
||||||
|
}
|
||||||
|
|
||||||
|
_.each(
|
||||||
|
children,
|
||||||
|
function (child) {
|
||||||
|
this._fixOverlapping(child, heightById);
|
||||||
},
|
},
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
_branchIsTaller: function (node, heightById) {
|
_shiftBranches(node, heightById) {
|
||||||
return (
|
const shiftedBranches = [node];
|
||||||
heightById[node.getId()] >
|
|
||||||
node.getSize().height + node.getSorter()._getVerticalPadding() * 2
|
const siblingsToShift = this._treeSet.getSiblingsInVerticalDirection(
|
||||||
);
|
node,
|
||||||
|
node.getFreeDisplacement().y,
|
||||||
|
);
|
||||||
|
let last = node;
|
||||||
|
_.each(
|
||||||
|
siblingsToShift,
|
||||||
|
function (sibling) {
|
||||||
|
const overlappingOccurs = shiftedBranches.some(function (shiftedBranch) {
|
||||||
|
return this._branchesOverlap(shiftedBranch, sibling, heightById);
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
if (!sibling.isFree() || overlappingOccurs) {
|
||||||
|
const sAmount = node.getFreeDisplacement().y;
|
||||||
|
this._treeSet.shiftBranchPosition(sibling, 0, sAmount);
|
||||||
|
shiftedBranches.push(sibling);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
|
||||||
_fixOverlapping: function (node, heightById) {
|
const branchesToShift = this._treeSet
|
||||||
var children = this._treeSet.getChildren(node);
|
.getBranchesInVerticalDirection(node, node.getFreeDisplacement().y)
|
||||||
|
.filter((branch) => !shiftedBranches.contains(branch));
|
||||||
|
|
||||||
if (node.isFree()) {
|
_.each(
|
||||||
this._shiftBranches(node, heightById);
|
branchesToShift,
|
||||||
}
|
function (branch) {
|
||||||
|
const bAmount = node.getFreeDisplacement().y;
|
||||||
_.each(
|
this._treeSet.shiftBranchPosition(branch, 0, bAmount);
|
||||||
children,
|
shiftedBranches.push(branch);
|
||||||
function (child) {
|
last = branch;
|
||||||
this._fixOverlapping(child, heightById);
|
|
||||||
},
|
|
||||||
this
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
_shiftBranches: function (node, heightById) {
|
_branchesOverlap(branchA, branchB, heightById) {
|
||||||
var shiftedBranches = [node];
|
// a branch doesn't really overlap with itself
|
||||||
|
if (branchA == branchB) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
var siblingsToShift = this._treeSet.getSiblingsInVerticalDirection(
|
const topA = branchA.getPosition().y - heightById[branchA.getId()] / 2;
|
||||||
node,
|
const bottomA = branchA.getPosition().y + heightById[branchA.getId()] / 2;
|
||||||
node.getFreeDisplacement().y
|
const topB = branchB.getPosition().y - heightById[branchB.getId()] / 2;
|
||||||
);
|
const bottomB = branchB.getPosition().y + heightById[branchB.getId()] / 2;
|
||||||
var last = node;
|
|
||||||
_.each(
|
|
||||||
siblingsToShift,
|
|
||||||
function (sibling) {
|
|
||||||
var overlappingOccurs = shiftedBranches.some(function (shiftedBranch) {
|
|
||||||
return this._branchesOverlap(shiftedBranch, sibling, heightById);
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
if (!sibling.isFree() || overlappingOccurs) {
|
return !(topA >= bottomB || bottomA <= topB);
|
||||||
var sAmount = node.getFreeDisplacement().y;
|
},
|
||||||
this._treeSet.shiftBranchPosition(sibling, 0, sAmount);
|
},
|
||||||
shiftedBranches.push(sibling);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
this
|
|
||||||
);
|
|
||||||
|
|
||||||
var branchesToShift = this._treeSet
|
|
||||||
.getBranchesInVerticalDirection(node, node.getFreeDisplacement().y)
|
|
||||||
.filter(function (branch) {
|
|
||||||
return !shiftedBranches.contains(branch);
|
|
||||||
});
|
|
||||||
|
|
||||||
_.each(
|
|
||||||
branchesToShift,
|
|
||||||
function (branch) {
|
|
||||||
var bAmount = node.getFreeDisplacement().y;
|
|
||||||
this._treeSet.shiftBranchPosition(branch, 0, bAmount);
|
|
||||||
shiftedBranches.push(branch);
|
|
||||||
last = branch;
|
|
||||||
},
|
|
||||||
this
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
_branchesOverlap: function (branchA, branchB, heightById) {
|
|
||||||
// a branch doesn't really overlap with itself
|
|
||||||
if (branchA == branchB) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var topA = branchA.getPosition().y - heightById[branchA.getId()] / 2;
|
|
||||||
var bottomA = branchA.getPosition().y + heightById[branchA.getId()] / 2;
|
|
||||||
var topB = branchB.getPosition().y - heightById[branchB.getId()] / 2;
|
|
||||||
var bottomB = branchB.getPosition().y + heightById[branchB.getId()] / 2;
|
|
||||||
|
|
||||||
return !(topA >= bottomB || bottomA <= topB);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,443 +17,437 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const RootedTreeSet = new Class(
|
const RootedTreeSet = new Class(
|
||||||
/** @lends RootedTreeSet */ {
|
/** @lends RootedTreeSet */ {
|
||||||
/** @constructs */
|
/** @constructs */
|
||||||
initialize: function () {
|
initialize() {
|
||||||
this._rootNodes = [];
|
this._rootNodes = [];
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param root
|
* @param root
|
||||||
* @throws will throw an error if root is null or undefined
|
* @throws will throw an error if root is null or undefined
|
||||||
*/
|
*/
|
||||||
setRoot: function (root) {
|
setRoot(root) {
|
||||||
$assert(root, 'root can not be null');
|
$assert(root, 'root can not be null');
|
||||||
this._rootNodes.push(this._decodate(root));
|
this._rootNodes.push(this._decodate(root));
|
||||||
},
|
},
|
||||||
|
|
||||||
/** getter */
|
/** getter */
|
||||||
getTreeRoots: function () {
|
getTreeRoots() {
|
||||||
return this._rootNodes;
|
return this._rootNodes;
|
||||||
},
|
},
|
||||||
|
|
||||||
_decodate: function (node) {
|
_decodate(node) {
|
||||||
node._children = [];
|
node._children = [];
|
||||||
return node;
|
return node;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {mindplot.model.NodeModel} node
|
* @param {mindplot.model.NodeModel} node
|
||||||
* @throws will throw an error if node is null or undefined
|
* @throws will throw an error if node is null or undefined
|
||||||
* @throws will throw an error if node with id already exists
|
* @throws will throw an error if node with id already exists
|
||||||
* @throws will throw an error if node has been added already
|
* @throws will throw an error if node has been added already
|
||||||
*/
|
*/
|
||||||
add: function (node) {
|
add(node) {
|
||||||
$assert(node, 'node can not be null');
|
$assert(node, 'node can not be null');
|
||||||
$assert(
|
$assert(
|
||||||
!this.find(node.getId(), false),
|
!this.find(node.getId(), false),
|
||||||
'node already exits with this id. Id:' + node.getId()
|
`node already exits with this id. Id:${node.getId()}`,
|
||||||
);
|
);
|
||||||
$assert(!node._children, 'node already added');
|
$assert(!node._children, 'node already added');
|
||||||
this._rootNodes.push(this._decodate(node));
|
this._rootNodes.push(this._decodate(node));
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param nodeId
|
* @param nodeId
|
||||||
* @throws will throw an error if nodeId is null or undefined
|
* @throws will throw an error if nodeId is null or undefined
|
||||||
*/
|
*/
|
||||||
remove: function (nodeId) {
|
remove(nodeId) {
|
||||||
$assert($defined(nodeId), 'nodeId can not be null');
|
$assert($defined(nodeId), 'nodeId can not be null');
|
||||||
var node = this.find(nodeId);
|
const node = this.find(nodeId);
|
||||||
this._rootNodes.erase(node);
|
this._rootNodes.erase(node);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param parentId
|
* @param parentId
|
||||||
* @param childId
|
* @param childId
|
||||||
* @throws will throw an error if parentId is null or undefined
|
* @throws will throw an error if parentId is null or undefined
|
||||||
* @throws will throw an error if childId is null or undefined
|
* @throws will throw an error if childId is null or undefined
|
||||||
* @throws will throw an error if node with id childId is already a child of parent
|
* @throws will throw an error if node with id childId is already a child of parent
|
||||||
*/
|
*/
|
||||||
connect: function (parentId, childId) {
|
connect(parentId, childId) {
|
||||||
$assert($defined(parentId), 'parent can not be null');
|
$assert($defined(parentId), 'parent can not be null');
|
||||||
$assert($defined(childId), 'child can not be null');
|
$assert($defined(childId), 'child can not be null');
|
||||||
|
|
||||||
var parent = this.find(parentId);
|
const parent = this.find(parentId);
|
||||||
var child = this.find(childId, true);
|
const child = this.find(childId, true);
|
||||||
$assert(
|
$assert(
|
||||||
!child._parent,
|
!child._parent,
|
||||||
'node already connected. Id:' + child.getId() + ',previous:' + child._parent
|
`node already connected. Id:${child.getId()},previous:${child._parent}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
parent._children.push(child);
|
parent._children.push(child);
|
||||||
child._parent = parent;
|
child._parent = parent;
|
||||||
this._rootNodes.erase(child);
|
this._rootNodes.erase(child);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param nodeId
|
* @param nodeId
|
||||||
* @throws will throw an error if nodeId is null or undefined
|
* @throws will throw an error if nodeId is null or undefined
|
||||||
* @throws will throw an error if node is not connected
|
* @throws will throw an error if node is not connected
|
||||||
*/
|
*/
|
||||||
disconnect: function (nodeId) {
|
disconnect(nodeId) {
|
||||||
$assert($defined(nodeId), 'nodeId can not be null');
|
$assert($defined(nodeId), 'nodeId can not be null');
|
||||||
var node = this.find(nodeId);
|
const node = this.find(nodeId);
|
||||||
$assert(node._parent, 'Node is not connected');
|
$assert(node._parent, 'Node is not connected');
|
||||||
|
|
||||||
node._parent._children.erase(node);
|
node._parent._children.erase(node);
|
||||||
this._rootNodes.push(node);
|
this._rootNodes.push(node);
|
||||||
node._parent = null;
|
node._parent = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param id
|
* @param id
|
||||||
* @param validate
|
* @param validate
|
||||||
* @throws will throw an error if id is null or undefined
|
* @throws will throw an error if id is null or undefined
|
||||||
* @throws will throw an error if node cannot be found
|
* @throws will throw an error if node cannot be found
|
||||||
* @return node
|
* @return node
|
||||||
*/
|
*/
|
||||||
find: function (id, validate) {
|
find(id, validate) {
|
||||||
$assert($defined(id), 'id can not be null');
|
$assert($defined(id), 'id can not be null');
|
||||||
|
|
||||||
var graphs = this._rootNodes;
|
const graphs = this._rootNodes;
|
||||||
var result = null;
|
let result = null;
|
||||||
for (var i = 0; i < graphs.length; i++) {
|
for (let i = 0; i < graphs.length; i++) {
|
||||||
var node = graphs[i];
|
const node = graphs[i];
|
||||||
result = this._find(id, node);
|
result = this._find(id, node);
|
||||||
if (result) {
|
if (result) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
validate = !$defined(validate) ? true : validate;
|
validate = !$defined(validate) ? true : validate;
|
||||||
$assert(
|
$assert(
|
||||||
validate ? result : true,
|
validate ? result : true,
|
||||||
'node could not be found id:' + id + '\n,RootedTreeSet' + this.dump()
|
`node could not be found id:${id}\n,RootedTreeSet${this.dump()}`,
|
||||||
);
|
);
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
_find: function (id, parent) {
|
_find(id, parent) {
|
||||||
if (parent.getId() == id) {
|
if (parent.getId() == id) {
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = null;
|
let result = null;
|
||||||
var children = parent._children;
|
const children = parent._children;
|
||||||
for (var i = 0; i < children.length; i++) {
|
for (let i = 0; i < children.length; i++) {
|
||||||
var child = children[i];
|
const child = children[i];
|
||||||
result = this._find(id, child);
|
result = this._find(id, child);
|
||||||
if (result) break;
|
if (result) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param node
|
* @param node
|
||||||
* @throws will throw an error if nodeId is null or undefined
|
* @throws will throw an error if nodeId is null or undefined
|
||||||
* @return children
|
* @return children
|
||||||
*/
|
*/
|
||||||
getChildren: function (node) {
|
getChildren(node) {
|
||||||
$assert(node, 'node cannot be null');
|
$assert(node, 'node cannot be null');
|
||||||
return node._children;
|
return node._children;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param node
|
* @param node
|
||||||
* @throws will throw an error if node is null or undefined
|
* @throws will throw an error if node is null or undefined
|
||||||
* @return root node or the provided node, if it has no parent
|
* @return root node or the provided node, if it has no parent
|
||||||
*/
|
*/
|
||||||
getRootNode: function (node) {
|
getRootNode(node) {
|
||||||
$assert(node, 'node cannot be null');
|
$assert(node, 'node cannot be null');
|
||||||
var parent = this.getParent(node);
|
const parent = this.getParent(node);
|
||||||
if ($defined(parent)) {
|
if ($defined(parent)) {
|
||||||
return this.getRootNode(parent);
|
return this.getRootNode(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param node
|
* @param node
|
||||||
* @throws will throw an error if node is null or undefined
|
* @throws will throw an error if node is null or undefined
|
||||||
* @return {Array} ancestors*/
|
* @return {Array} ancestors */
|
||||||
getAncestors: function (node) {
|
getAncestors(node) {
|
||||||
$assert(node, 'node cannot be null');
|
$assert(node, 'node cannot be null');
|
||||||
return this._getAncestors(this.getParent(node), []);
|
return this._getAncestors(this.getParent(node), []);
|
||||||
},
|
},
|
||||||
|
|
||||||
_getAncestors: function (node, ancestors) {
|
_getAncestors(node, ancestors) {
|
||||||
var result = ancestors;
|
const result = ancestors;
|
||||||
if (node) {
|
if (node) {
|
||||||
result.push(node);
|
result.push(node);
|
||||||
this._getAncestors(this.getParent(node), result);
|
this._getAncestors(this.getParent(node), result);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param node
|
* @param node
|
||||||
* @throws will throw an error if node is null or undefined
|
* @throws will throw an error if node is null or undefined
|
||||||
* @return {Array} siblings
|
* @return {Array} siblings
|
||||||
*/
|
*/
|
||||||
getSiblings: function (node) {
|
getSiblings(node) {
|
||||||
$assert(node, 'node cannot be null');
|
$assert(node, 'node cannot be null');
|
||||||
if (!$defined(node._parent)) {
|
if (!$defined(node._parent)) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
var siblings = node._parent._children.filter(function (child) {
|
const siblings = node._parent._children.filter((child) => child != node);
|
||||||
return child != node;
|
return siblings;
|
||||||
});
|
},
|
||||||
return siblings;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param node
|
* @param node
|
||||||
* @throws will throw an error if node is null or undefined
|
* @throws will throw an error if node is null or undefined
|
||||||
* @return {Boolean} whether the node has a single path to a single leaf (no branching)
|
* @return {Boolean} whether the node has a single path to a single leaf (no branching)
|
||||||
*/
|
*/
|
||||||
hasSinglePathToSingleLeaf: function (node) {
|
hasSinglePathToSingleLeaf(node) {
|
||||||
$assert(node, 'node cannot be null');
|
$assert(node, 'node cannot be null');
|
||||||
return this._hasSinglePathToSingleLeaf(node);
|
return this._hasSinglePathToSingleLeaf(node);
|
||||||
},
|
},
|
||||||
|
|
||||||
_hasSinglePathToSingleLeaf: function (node) {
|
_hasSinglePathToSingleLeaf(node) {
|
||||||
var children = this.getChildren(node);
|
const children = this.getChildren(node);
|
||||||
|
|
||||||
if (children.length == 1) {
|
if (children.length == 1) {
|
||||||
return this._hasSinglePathToSingleLeaf(children[0]);
|
return this._hasSinglePathToSingleLeaf(children[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return children.length == 0;
|
return children.length == 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param node
|
* @param node
|
||||||
* @return {Boolean} whether the node is the start of a subbranch*/
|
* @return {Boolean} whether the node is the start of a subbranch */
|
||||||
isStartOfSubBranch: function (node) {
|
isStartOfSubBranch(node) {
|
||||||
return this.getSiblings(node).length > 0 && this.getChildren(node).length == 1;
|
return this.getSiblings(node).length > 0 && this.getChildren(node).length == 1;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param node
|
* @param node
|
||||||
* @throws will throw an error if node is null or undefined
|
* @throws will throw an error if node is null or undefined
|
||||||
* @return {Boolean} whether the node is a leaf
|
* @return {Boolean} whether the node is a leaf
|
||||||
*/
|
*/
|
||||||
isLeaf: function (node) {
|
isLeaf(node) {
|
||||||
$assert(node, 'node cannot be null');
|
$assert(node, 'node cannot be null');
|
||||||
return this.getChildren(node).length == 0;
|
return this.getChildren(node).length == 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param node
|
* @param node
|
||||||
* @throws will throw an error if node is null or undefined
|
* @throws will throw an error if node is null or undefined
|
||||||
* @return parent
|
* @return parent
|
||||||
*/
|
*/
|
||||||
getParent: function (node) {
|
getParent(node) {
|
||||||
$assert(node, 'node cannot be null');
|
$assert(node, 'node cannot be null');
|
||||||
return node._parent;
|
return node._parent;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return result
|
* @return result
|
||||||
*/
|
*/
|
||||||
dump: function () {
|
dump() {
|
||||||
var branches = this._rootNodes;
|
const branches = this._rootNodes;
|
||||||
var result = '';
|
let result = '';
|
||||||
for (var i = 0; i < branches.length; i++) {
|
for (let i = 0; i < branches.length; i++) {
|
||||||
var branch = branches[i];
|
const branch = branches[i];
|
||||||
result += this._dump(branch, '');
|
result += this._dump(branch, '');
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
_dump: function (node, indent) {
|
_dump(node, indent) {
|
||||||
var result = indent + node + '\n';
|
let result = `${indent + node}\n`;
|
||||||
var children = this.getChildren(node);
|
const children = this.getChildren(node);
|
||||||
for (var i = 0; i < children.length; i++) {
|
for (let i = 0; i < children.length; i++) {
|
||||||
var child = children[i];
|
const child = children[i];
|
||||||
result += this._dump(child, indent + ' ');
|
result += this._dump(child, `${indent} `);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param canvas
|
* @param canvas
|
||||||
*/
|
*/
|
||||||
plot: function (canvas) {
|
plot(canvas) {
|
||||||
var branches = this._rootNodes;
|
const branches = this._rootNodes;
|
||||||
for (var i = 0; i < branches.length; i++) {
|
for (let i = 0; i < branches.length; i++) {
|
||||||
var branch = branches[i];
|
const branch = branches[i];
|
||||||
this._plot(canvas, branch);
|
this._plot(canvas, branch);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_plot: function (canvas, node, root) {
|
_plot(canvas, node, root) {
|
||||||
var children = this.getChildren(node);
|
const children = this.getChildren(node);
|
||||||
var cx = node.getPosition().x + canvas.width / 2 - node.getSize().width / 2;
|
const cx = node.getPosition().x + canvas.width / 2 - node.getSize().width / 2;
|
||||||
var cy = node.getPosition().y + canvas.height / 2 - node.getSize().height / 2;
|
const cy = node.getPosition().y + canvas.height / 2 - node.getSize().height / 2;
|
||||||
var rect = canvas.rect(cx, cy, node.getSize().width, node.getSize().height);
|
const rect = canvas.rect(cx, cy, node.getSize().width, node.getSize().height);
|
||||||
var order = node.getOrder() == null ? 'r' : node.getOrder();
|
const order = node.getOrder() == null ? 'r' : node.getOrder();
|
||||||
var text = canvas.text(
|
const text = canvas.text(
|
||||||
node.getPosition().x + canvas.width / 2,
|
node.getPosition().x + canvas.width / 2,
|
||||||
node.getPosition().y + canvas.height / 2,
|
node.getPosition().y + canvas.height / 2,
|
||||||
node.getId() + '[' + order + ']'
|
`${node.getId()}[${order}]`,
|
||||||
);
|
);
|
||||||
text.attr('fill', '#FFF');
|
text.attr('fill', '#FFF');
|
||||||
var fillColor = this._rootNodes.contains(node)
|
const fillColor = this._rootNodes.contains(node)
|
||||||
? '#000'
|
? '#000'
|
||||||
: node.isFree()
|
: node.isFree()
|
||||||
? '#abc'
|
? '#abc'
|
||||||
: '#c00';
|
: '#c00';
|
||||||
rect.attr('fill', fillColor);
|
rect.attr('fill', fillColor);
|
||||||
|
|
||||||
var rectPosition = {
|
const rectPosition = {
|
||||||
x: rect.attr('x') - canvas.width / 2 + rect.attr('width') / 2,
|
x: rect.attr('x') - canvas.width / 2 + rect.attr('width') / 2,
|
||||||
y: rect.attr('y') - canvas.height / 2 + rect.attr('height') / 2,
|
y: rect.attr('y') - canvas.height / 2 + rect.attr('height') / 2,
|
||||||
};
|
};
|
||||||
var rectSize = { width: rect.attr('width'), height: rect.attr('height') };
|
const rectSize = { width: rect.attr('width'), height: rect.attr('height') };
|
||||||
rect.click(function () {
|
rect.click(() => {
|
||||||
console.log(
|
console.log(
|
||||||
'[id:' +
|
`[id:${
|
||||||
node.getId() +
|
node.getId()
|
||||||
', order:' +
|
}, order:${
|
||||||
node.getOrder() +
|
node.getOrder()
|
||||||
', position:(' +
|
}, position:(${
|
||||||
rectPosition.x +
|
rectPosition.x
|
||||||
',' +
|
},${
|
||||||
rectPosition.y +
|
rectPosition.y
|
||||||
'), size:' +
|
}), size:${
|
||||||
rectSize.width +
|
rectSize.width
|
||||||
'x' +
|
}x${
|
||||||
rectSize.height +
|
rectSize.height
|
||||||
', freeDisplacement:(' +
|
}, freeDisplacement:(${
|
||||||
node.getFreeDisplacement().x +
|
node.getFreeDisplacement().x
|
||||||
',' +
|
},${
|
||||||
node.getFreeDisplacement().y +
|
node.getFreeDisplacement().y
|
||||||
')]'
|
})]`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
text.click(function () {
|
text.click(() => {
|
||||||
console.log(
|
console.log(
|
||||||
'[id:' +
|
`[id:${
|
||||||
node.getId() +
|
node.getId()
|
||||||
', order:' +
|
}, order:${
|
||||||
node.getOrder() +
|
node.getOrder()
|
||||||
', position:(' +
|
}, position:(${
|
||||||
rectPosition.x +
|
rectPosition.x
|
||||||
',' +
|
},${
|
||||||
rectPosition.y +
|
rectPosition.y
|
||||||
'), size:' +
|
}), size:${
|
||||||
rectSize.width +
|
rectSize.width
|
||||||
'x' +
|
}x${
|
||||||
rectSize.height +
|
rectSize.height
|
||||||
', freeDisplacement:(' +
|
}, freeDisplacement:(${
|
||||||
node.getFreeDisplacement().x +
|
node.getFreeDisplacement().x
|
||||||
',' +
|
},${
|
||||||
node.getFreeDisplacement().y +
|
node.getFreeDisplacement().y
|
||||||
')]'
|
})]`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
for (var i = 0; i < children.length; i++) {
|
for (let i = 0; i < children.length; i++) {
|
||||||
var child = children[i];
|
const child = children[i];
|
||||||
this._plot(canvas, child);
|
this._plot(canvas, child);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param node
|
* @param node
|
||||||
* @param position
|
* @param position
|
||||||
*/
|
*/
|
||||||
updateBranchPosition: function (node, position) {
|
updateBranchPosition(node, position) {
|
||||||
var oldPos = node.getPosition();
|
const oldPos = node.getPosition();
|
||||||
node.setPosition(position);
|
node.setPosition(position);
|
||||||
|
|
||||||
var xOffset = oldPos.x - position.x;
|
const xOffset = oldPos.x - position.x;
|
||||||
var yOffset = oldPos.y - position.y;
|
const yOffset = oldPos.y - position.y;
|
||||||
|
|
||||||
var children = this.getChildren(node);
|
const children = this.getChildren(node);
|
||||||
var me = this;
|
const me = this;
|
||||||
_.each(children, function (child) {
|
_.each(children, (child) => {
|
||||||
me.shiftBranchPosition(child, xOffset, yOffset);
|
me.shiftBranchPosition(child, xOffset, yOffset);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param node
|
* @param node
|
||||||
* @param xOffset
|
* @param xOffset
|
||||||
* @param yOffset
|
* @param yOffset
|
||||||
*/
|
*/
|
||||||
shiftBranchPosition: function (node, xOffset, yOffset) {
|
shiftBranchPosition(node, xOffset, yOffset) {
|
||||||
var position = node.getPosition();
|
const position = node.getPosition();
|
||||||
node.setPosition({ x: position.x + xOffset, y: position.y + yOffset });
|
node.setPosition({ x: position.x + xOffset, y: position.y + yOffset });
|
||||||
|
|
||||||
var children = this.getChildren(node);
|
const children = this.getChildren(node);
|
||||||
var me = this;
|
const me = this;
|
||||||
_.each(children, function (child) {
|
_.each(children, (child) => {
|
||||||
me.shiftBranchPosition(child, xOffset, yOffset);
|
me.shiftBranchPosition(child, xOffset, yOffset);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param node
|
* @param node
|
||||||
* @param yOffset
|
* @param yOffset
|
||||||
* @return siblings in the offset (vertical) direction, i.e. with lower or higher order, respectively
|
* @return siblings in the offset (vertical) direction, i.e. with lower or higher order, respectively
|
||||||
*/
|
*/
|
||||||
getSiblingsInVerticalDirection: function (node, yOffset) {
|
getSiblingsInVerticalDirection(node, yOffset) {
|
||||||
// siblings with lower or higher order, depending on the direction of the offset and on the same side as their parent
|
// siblings with lower or higher order, depending on the direction of the offset and on the same side as their parent
|
||||||
var parent = this.getParent(node);
|
const parent = this.getParent(node);
|
||||||
var siblings = this.getSiblings(node).filter(function (sibling) {
|
const siblings = this.getSiblings(node).filter((sibling) => {
|
||||||
var sameSide =
|
const sameSide = node.getPosition().x > parent.getPosition().x
|
||||||
node.getPosition().x > parent.getPosition().x
|
? sibling.getPosition().x > parent.getPosition().x
|
||||||
? sibling.getPosition().x > parent.getPosition().x
|
: sibling.getPosition().x < parent.getPosition().x;
|
||||||
: sibling.getPosition().x < parent.getPosition().x;
|
const orderOK = yOffset < 0
|
||||||
var orderOK =
|
? sibling.getOrder() < node.getOrder()
|
||||||
yOffset < 0
|
: sibling.getOrder() > node.getOrder();
|
||||||
? sibling.getOrder() < node.getOrder()
|
return orderOK && sameSide;
|
||||||
: sibling.getOrder() > node.getOrder();
|
});
|
||||||
return orderOK && sameSide;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (yOffset < 0) {
|
if (yOffset < 0) {
|
||||||
siblings.reverse();
|
siblings.reverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
return siblings;
|
return siblings;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param node
|
* @param node
|
||||||
* @param yOffset
|
* @param yOffset
|
||||||
* @return branches of the root node on the same side as the given node's, in the given
|
* @return branches of the root node on the same side as the given node's, in the given
|
||||||
* vertical direction
|
* vertical direction
|
||||||
*/
|
*/
|
||||||
getBranchesInVerticalDirection: function (node, yOffset) {
|
getBranchesInVerticalDirection(node, yOffset) {
|
||||||
// direct descendants of the root that do not contain the node and are on the same side
|
// direct descendants of the root that do not contain the node and are on the same side
|
||||||
// and on the direction of the offset
|
// and on the direction of the offset
|
||||||
var rootNode = this.getRootNode(node);
|
const rootNode = this.getRootNode(node);
|
||||||
var branches = this.getChildren(rootNode).filter(function (child) {
|
const branches = this.getChildren(rootNode).filter(function (child) {
|
||||||
return this._find(node.getId(), child);
|
return this._find(node.getId(), child);
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
var branch = branches[0];
|
const branch = branches[0];
|
||||||
var rootDescendants = this.getSiblings(branch).filter(function (sibling) {
|
const rootDescendants = this.getSiblings(branch).filter((sibling) => {
|
||||||
var sameSide =
|
const sameSide = node.getPosition().x > rootNode.getPosition().x
|
||||||
node.getPosition().x > rootNode.getPosition().x
|
? sibling.getPosition().x > rootNode.getPosition().x
|
||||||
? sibling.getPosition().x > rootNode.getPosition().x
|
: sibling.getPosition().x < rootNode.getPosition().x;
|
||||||
: sibling.getPosition().x < rootNode.getPosition().x;
|
const sameDirection = yOffset < 0
|
||||||
var sameDirection =
|
? sibling.getOrder() < branch.getOrder()
|
||||||
yOffset < 0
|
: sibling.getOrder() > branch.getOrder();
|
||||||
? sibling.getOrder() < branch.getOrder()
|
return sameSide && sameDirection;
|
||||||
: sibling.getOrder() > branch.getOrder();
|
}, this);
|
||||||
return sameSide && sameDirection;
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
return rootDescendants;
|
return rootDescendants;
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
export default RootedTreeSet;
|
export default RootedTreeSet;
|
||||||
|
@ -18,15 +18,15 @@
|
|||||||
const AbstractBasicSorter = require('./AbstractBasicSorter').default;
|
const AbstractBasicSorter = require('./AbstractBasicSorter').default;
|
||||||
|
|
||||||
const SymmetricSorter = new Class(
|
const SymmetricSorter = new Class(
|
||||||
/** @lends SymmetricSorter */ {
|
/** @lends SymmetricSorter */ {
|
||||||
Extends: AbstractBasicSorter,
|
Extends: AbstractBasicSorter,
|
||||||
/**
|
/**
|
||||||
* @constructs
|
* @constructs
|
||||||
* @extends mindplot.layout.AbstractBasicSorter
|
* @extends mindplot.layout.AbstractBasicSorter
|
||||||
*/
|
*/
|
||||||
initialize: function () {},
|
initialize() {},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Predict the order and position of a dragged node.
|
* Predict the order and position of a dragged node.
|
||||||
*
|
*
|
||||||
* @param graph The tree set
|
* @param graph The tree set
|
||||||
@ -36,190 +36,184 @@ const SymmetricSorter = new Class(
|
|||||||
* @param free Free drag or not
|
* @param free Free drag or not
|
||||||
* @return {*}
|
* @return {*}
|
||||||
*/
|
*/
|
||||||
predict: function (graph, parent, node, position, free) {
|
predict(graph, parent, node, position, free) {
|
||||||
var self = this;
|
const self = this;
|
||||||
var rootNode = graph.getRootNode(parent);
|
const rootNode = graph.getRootNode(parent);
|
||||||
|
|
||||||
// If its a free node...
|
// If its a free node...
|
||||||
if (free) {
|
if (free) {
|
||||||
$assert(
|
$assert(
|
||||||
$defined(position),
|
$defined(position),
|
||||||
'position cannot be null for predict in free positioning'
|
'position cannot be null for predict in free positioning',
|
||||||
);
|
);
|
||||||
$assert($defined(node), 'node cannot be null for predict in free positioning');
|
$assert($defined(node), 'node cannot be null for predict in free positioning');
|
||||||
|
|
||||||
var direction = this._getRelativeDirection(
|
const direction = this._getRelativeDirection(
|
||||||
rootNode.getPosition(),
|
rootNode.getPosition(),
|
||||||
parent.getPosition()
|
parent.getPosition(),
|
||||||
);
|
);
|
||||||
var limitXPos =
|
const limitXPos = parent.getPosition().x
|
||||||
parent.getPosition().x +
|
+ direction
|
||||||
direction *
|
* (parent.getSize().width / 2
|
||||||
(parent.getSize().width / 2 +
|
+ node.getSize().width / 2
|
||||||
node.getSize().width / 2 +
|
+ SymmetricSorter.INTERNODE_HORIZONTAL_PADDING);
|
||||||
SymmetricSorter.INTERNODE_HORIZONTAL_PADDING);
|
|
||||||
|
|
||||||
var xPos =
|
const xPos = direction > 0
|
||||||
direction > 0
|
? position.x >= limitXPos
|
||||||
? position.x >= limitXPos
|
? position.x
|
||||||
? position.x
|
: limitXPos
|
||||||
: limitXPos
|
: position.x <= limitXPos
|
||||||
: position.x <= limitXPos
|
? position.x
|
||||||
? position.x
|
: limitXPos;
|
||||||
: limitXPos;
|
|
||||||
|
|
||||||
return [0, { x: xPos, y: position.y }];
|
return [0, { x: xPos, y: position.y }];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Its not a dragged node (it is being added)
|
// Its not a dragged node (it is being added)
|
||||||
if (!node) {
|
if (!node) {
|
||||||
var parentDirection = self._getRelativeDirection(
|
const parentDirection = self._getRelativeDirection(
|
||||||
rootNode.getPosition(),
|
rootNode.getPosition(),
|
||||||
parent.getPosition()
|
parent.getPosition(),
|
||||||
);
|
);
|
||||||
|
|
||||||
var position = {
|
var position = {
|
||||||
x:
|
x:
|
||||||
parent.getPosition().x +
|
parent.getPosition().x
|
||||||
parentDirection *
|
+ parentDirection
|
||||||
(parent.getSize().width + SymmetricSorter.INTERNODE_HORIZONTAL_PADDING),
|
* (parent.getSize().width + SymmetricSorter.INTERNODE_HORIZONTAL_PADDING),
|
||||||
y: parent.getPosition().y,
|
y: parent.getPosition().y,
|
||||||
};
|
};
|
||||||
return [graph.getChildren(parent).length, position];
|
return [graph.getChildren(parent).length, position];
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it is a dragged node...
|
// If it is a dragged node...
|
||||||
$assert($defined(position), 'position cannot be null for predict in dragging');
|
$assert($defined(position), 'position cannot be null for predict in dragging');
|
||||||
var nodeDirection = this._getRelativeDirection(
|
const nodeDirection = this._getRelativeDirection(
|
||||||
rootNode.getPosition(),
|
rootNode.getPosition(),
|
||||||
node.getPosition()
|
node.getPosition(),
|
||||||
);
|
);
|
||||||
var positionDirection = this._getRelativeDirection(rootNode.getPosition(), position);
|
const positionDirection = this._getRelativeDirection(rootNode.getPosition(), position);
|
||||||
var siblings = graph.getSiblings(node);
|
const siblings = graph.getSiblings(node);
|
||||||
|
|
||||||
// node has no siblings and its trying to reconnect to its own parent
|
// node has no siblings and its trying to reconnect to its own parent
|
||||||
var sameParent = parent == graph.getParent(node);
|
const sameParent = parent == graph.getParent(node);
|
||||||
if (siblings.length == 0 && nodeDirection == positionDirection && sameParent) {
|
if (siblings.length == 0 && nodeDirection == positionDirection && sameParent) {
|
||||||
return [node.getOrder(), node.getPosition()];
|
return [node.getOrder(), node.getPosition()];
|
||||||
}
|
}
|
||||||
|
|
||||||
var parentChildren = graph.getChildren(parent);
|
const parentChildren = graph.getChildren(parent);
|
||||||
|
|
||||||
if (parentChildren.length == 0) {
|
if (parentChildren.length == 0) {
|
||||||
// Fit as a child of the parent node...
|
// Fit as a child of the parent node...
|
||||||
var position = {
|
var position = {
|
||||||
x:
|
x:
|
||||||
parent.getPosition().x +
|
parent.getPosition().x
|
||||||
positionDirection *
|
+ positionDirection
|
||||||
(parent.getSize().width + SymmetricSorter.INTERNODE_HORIZONTAL_PADDING),
|
* (parent.getSize().width + SymmetricSorter.INTERNODE_HORIZONTAL_PADDING),
|
||||||
y: parent.getPosition().y,
|
y: parent.getPosition().y,
|
||||||
};
|
};
|
||||||
return [0, position];
|
return [0, position];
|
||||||
} else {
|
}
|
||||||
// Try to fit within ...
|
// Try to fit within ...
|
||||||
var result = null;
|
const result = null;
|
||||||
var last = parentChildren.getLast();
|
const last = parentChildren.getLast();
|
||||||
for (var i = 0; i < parentChildren.length; i++) {
|
for (let i = 0; i < parentChildren.length; i++) {
|
||||||
var parentChild = parentChildren[i];
|
const parentChild = parentChildren[i];
|
||||||
var nodeAfter = i + 1 == parentChild.length ? null : parentChildren[i + 1];
|
const nodeAfter = i + 1 == parentChild.length ? null : parentChildren[i + 1];
|
||||||
|
|
||||||
// Fit at the bottom
|
// Fit at the bottom
|
||||||
if (!nodeAfter && position.y > parentChild.getPosition().y) {
|
if (!nodeAfter && position.y > parentChild.getPosition().y) {
|
||||||
var order =
|
var order = graph.getParent(node) && graph.getParent(node).getId() == parent.getId()
|
||||||
graph.getParent(node) && graph.getParent(node).getId() == parent.getId()
|
? last.getOrder()
|
||||||
? last.getOrder()
|
: last.getOrder() + 1;
|
||||||
: last.getOrder() + 1;
|
var position = {
|
||||||
var position = {
|
x: parentChild.getPosition().x,
|
||||||
x: parentChild.getPosition().x,
|
y:
|
||||||
y:
|
parentChild.getPosition().y
|
||||||
parentChild.getPosition().y +
|
+ parentChild.getSize().height
|
||||||
parentChild.getSize().height +
|
+ SymmetricSorter.INTERNODE_VERTICAL_PADDING * 2,
|
||||||
SymmetricSorter.INTERNODE_VERTICAL_PADDING * 2,
|
};
|
||||||
};
|
return [order, position];
|
||||||
return [order, position];
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Fit after this node
|
// Fit after this node
|
||||||
if (
|
if (
|
||||||
nodeAfter &&
|
nodeAfter
|
||||||
position.y > parentChild.getPosition().y &&
|
&& position.y > parentChild.getPosition().y
|
||||||
position.y < nodeAfter.getPosition().y
|
&& position.y < nodeAfter.getPosition().y
|
||||||
) {
|
) {
|
||||||
if (
|
if (
|
||||||
nodeAfter.getId() == node.getId() ||
|
nodeAfter.getId() == node.getId()
|
||||||
parentChild.getId() == node.getId()
|
|| parentChild.getId() == node.getId()
|
||||||
) {
|
) {
|
||||||
return [node.getOrder(), node.getPosition()];
|
return [node.getOrder(), node.getPosition()];
|
||||||
} else {
|
}
|
||||||
var order =
|
var order = position.y > node.getPosition().y
|
||||||
position.y > node.getPosition().y
|
? nodeAfter.getOrder() - 1
|
||||||
? nodeAfter.getOrder() - 1
|
: parentChild.getOrder() + 1;
|
||||||
: parentChild.getOrder() + 1;
|
var position = {
|
||||||
var position = {
|
x: parentChild.getPosition().x,
|
||||||
x: parentChild.getPosition().x,
|
y:
|
||||||
y:
|
parentChild.getPosition().y
|
||||||
parentChild.getPosition().y +
|
+ (nodeAfter.getPosition().y - parentChild.getPosition().y) / 2,
|
||||||
(nodeAfter.getPosition().y - parentChild.getPosition().y) / 2,
|
};
|
||||||
};
|
return [order, position];
|
||||||
return [order, position];
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Position wasn't below any node, so it must be fitted above the first
|
// Position wasn't below any node, so it must be fitted above the first
|
||||||
var first = parentChildren[0];
|
const first = parentChildren[0];
|
||||||
var position = {
|
var position = {
|
||||||
x: first.getPosition().x,
|
x: first.getPosition().x,
|
||||||
y:
|
y:
|
||||||
first.getPosition().y -
|
first.getPosition().y
|
||||||
first.getSize().height -
|
- first.getSize().height
|
||||||
SymmetricSorter.INTERNODE_VERTICAL_PADDING * 2,
|
- SymmetricSorter.INTERNODE_VERTICAL_PADDING * 2,
|
||||||
};
|
};
|
||||||
return [0, position];
|
return [0, position];
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param treeSet
|
* @param treeSet
|
||||||
* @param parent
|
* @param parent
|
||||||
* @param child
|
* @param child
|
||||||
* @param order
|
* @param order
|
||||||
* @throws will throw an error if the order is not strictly continuous
|
* @throws will throw an error if the order is not strictly continuous
|
||||||
*/
|
*/
|
||||||
insert: function (treeSet, parent, child, order) {
|
insert(treeSet, parent, child, order) {
|
||||||
var children = this._getSortedChildren(treeSet, parent);
|
const children = this._getSortedChildren(treeSet, parent);
|
||||||
$assert(
|
$assert(
|
||||||
order <= children.length,
|
order <= children.length,
|
||||||
'Order must be continues and can not have holes. Order:' + order
|
`Order must be continues and can not have holes. Order:${order}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Shift all the elements in one .
|
// Shift all the elements in one .
|
||||||
for (var i = order; i < children.length; i++) {
|
for (let i = order; i < children.length; i++) {
|
||||||
var node = children[i];
|
const node = children[i];
|
||||||
node.setOrder(i + 1);
|
node.setOrder(i + 1);
|
||||||
}
|
}
|
||||||
child.setOrder(order);
|
child.setOrder(order);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param treeSet
|
* @param treeSet
|
||||||
* @param node
|
* @param node
|
||||||
* @throws will throw an error if the node is in the wrong position*/
|
* @throws will throw an error if the node is in the wrong position */
|
||||||
detach: function (treeSet, node) {
|
detach(treeSet, node) {
|
||||||
var parent = treeSet.getParent(node);
|
const parent = treeSet.getParent(node);
|
||||||
var children = this._getSortedChildren(treeSet, parent);
|
const children = this._getSortedChildren(treeSet, parent);
|
||||||
var order = node.getOrder();
|
const order = node.getOrder();
|
||||||
$assert(children[order] === node, 'Node seems not to be in the right position');
|
$assert(children[order] === node, 'Node seems not to be in the right position');
|
||||||
|
|
||||||
// Shift all the nodes ...
|
// Shift all the nodes ...
|
||||||
for (var i = node.getOrder() + 1; i < children.length; i++) {
|
for (let i = node.getOrder() + 1; i < children.length; i++) {
|
||||||
var child = children[i];
|
const child = children[i];
|
||||||
child.setOrder(child.getOrder() - 1);
|
child.setOrder(child.getOrder() - 1);
|
||||||
}
|
}
|
||||||
node.setOrder(0);
|
node.setOrder(0);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param treeSet
|
* @param treeSet
|
||||||
* @param node
|
* @param node
|
||||||
* @throws will throw an error if treeSet is null or undefined
|
* @throws will throw an error if treeSet is null or undefined
|
||||||
@ -230,100 +224,99 @@ const SymmetricSorter = new Class(
|
|||||||
* value, is null or undefined
|
* value, is null or undefined
|
||||||
* @return offsets
|
* @return offsets
|
||||||
*/
|
*/
|
||||||
computeOffsets: function (treeSet, node) {
|
computeOffsets(treeSet, node) {
|
||||||
$assert(treeSet, 'treeSet can no be null.');
|
$assert(treeSet, 'treeSet can no be null.');
|
||||||
$assert(node, 'node can no be null.');
|
$assert(node, 'node can no be null.');
|
||||||
|
|
||||||
var children = this._getSortedChildren(treeSet, node);
|
const children = this._getSortedChildren(treeSet, node);
|
||||||
|
|
||||||
// Compute heights ...
|
// Compute heights ...
|
||||||
var heights = children
|
const heights = children
|
||||||
.map(function (child) {
|
.map(function (child) {
|
||||||
return {
|
return {
|
||||||
id: child.getId(),
|
id: child.getId(),
|
||||||
order: child.getOrder(),
|
order: child.getOrder(),
|
||||||
position: child.getPosition(),
|
position: child.getPosition(),
|
||||||
width: child.getSize().width,
|
width: child.getSize().width,
|
||||||
height: this._computeChildrenHeight(treeSet, child),
|
height: this._computeChildrenHeight(treeSet, child),
|
||||||
};
|
};
|
||||||
}, this)
|
}, this)
|
||||||
.reverse();
|
.reverse();
|
||||||
|
|
||||||
// Compute the center of the branch ...
|
// Compute the center of the branch ...
|
||||||
var totalHeight = 0;
|
let totalHeight = 0;
|
||||||
_.each(heights, function (elem) {
|
_.each(heights, (elem) => {
|
||||||
totalHeight += elem.height;
|
totalHeight += elem.height;
|
||||||
});
|
});
|
||||||
var ysum = totalHeight / 2;
|
let ysum = totalHeight / 2;
|
||||||
|
|
||||||
// Calculate the offsets ...
|
// Calculate the offsets ...
|
||||||
var result = {};
|
const result = {};
|
||||||
for (var i = 0; i < heights.length; i++) {
|
for (let i = 0; i < heights.length; i++) {
|
||||||
ysum = ysum - heights[i].height;
|
ysum -= heights[i].height;
|
||||||
var childNode = treeSet.find(heights[i].id);
|
const childNode = treeSet.find(heights[i].id);
|
||||||
var direction = this.getChildDirection(treeSet, childNode);
|
const direction = this.getChildDirection(treeSet, childNode);
|
||||||
|
|
||||||
var yOffset = ysum + heights[i].height / 2;
|
const yOffset = ysum + heights[i].height / 2;
|
||||||
var xOffset =
|
const xOffset = direction
|
||||||
direction *
|
* (heights[i].width / 2
|
||||||
(heights[i].width / 2 +
|
+ node.getSize().width / 2
|
||||||
node.getSize().width / 2 +
|
+ SymmetricSorter.INTERNODE_HORIZONTAL_PADDING);
|
||||||
SymmetricSorter.INTERNODE_HORIZONTAL_PADDING);
|
|
||||||
|
|
||||||
$assert(!isNaN(xOffset), 'xOffset can not be null');
|
$assert(!isNaN(xOffset), 'xOffset can not be null');
|
||||||
$assert(!isNaN(yOffset), 'yOffset can not be null');
|
$assert(!isNaN(yOffset), 'yOffset can not be null');
|
||||||
|
|
||||||
result[heights[i].id] = { x: xOffset, y: yOffset };
|
result[heights[i].id] = { x: xOffset, y: yOffset };
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param treeSet
|
* @param treeSet
|
||||||
* @param node
|
* @param node
|
||||||
* @throws will throw an error if order elements are missing
|
* @throws will throw an error if order elements are missing
|
||||||
*/
|
*/
|
||||||
verify: function (treeSet, node) {
|
verify(treeSet, node) {
|
||||||
// Check that all is consistent ...
|
// Check that all is consistent ...
|
||||||
var children = this._getSortedChildren(treeSet, node);
|
const children = this._getSortedChildren(treeSet, node);
|
||||||
|
|
||||||
for (var i = 0; i < children.length; i++) {
|
for (let i = 0; i < children.length; i++) {
|
||||||
$assert(children[i].getOrder() == i, 'missing order elements');
|
$assert(children[i].getOrder() == i, 'missing order elements');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param treeSet
|
* @param treeSet
|
||||||
* @param child
|
* @param child
|
||||||
* @return direction of the given child from its parent or from the root node, if isolated*/
|
* @return direction of the given child from its parent or from the root node, if isolated */
|
||||||
getChildDirection: function (treeSet, child) {
|
getChildDirection(treeSet, child) {
|
||||||
$assert(treeSet, 'treeSet can no be null.');
|
$assert(treeSet, 'treeSet can no be null.');
|
||||||
$assert(treeSet.getParent(child), 'This should not happen');
|
$assert(treeSet.getParent(child), 'This should not happen');
|
||||||
|
|
||||||
var result;
|
let result;
|
||||||
var rootNode = treeSet.getRootNode(child);
|
const rootNode = treeSet.getRootNode(child);
|
||||||
if (treeSet.getParent(child) == rootNode) {
|
if (treeSet.getParent(child) == rootNode) {
|
||||||
// This is the case of a isolated child ... In this case, the directions is based on the root.
|
// This is the case of a isolated child ... In this case, the directions is based on the root.
|
||||||
result = Math.sign(rootNode.getPosition().x);
|
result = Math.sign(rootNode.getPosition().x);
|
||||||
} else {
|
} else {
|
||||||
// if this is not the case, honor the direction of the parent ...
|
// if this is not the case, honor the direction of the parent ...
|
||||||
var parent = treeSet.getParent(child);
|
const parent = treeSet.getParent(child);
|
||||||
var grandParent = treeSet.getParent(parent);
|
const grandParent = treeSet.getParent(parent);
|
||||||
var sorter = grandParent.getSorter();
|
const sorter = grandParent.getSorter();
|
||||||
result = sorter.getChildDirection(treeSet, parent);
|
result = sorter.getChildDirection(treeSet, parent);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @return {String} the print name of this class */
|
/** @return {String} the print name of this class */
|
||||||
toString: function () {
|
toString() {
|
||||||
return 'Symmetric Sorter';
|
return 'Symmetric Sorter';
|
||||||
},
|
},
|
||||||
|
|
||||||
_getVerticalPadding: function () {
|
_getVerticalPadding() {
|
||||||
return SymmetricSorter.INTERNODE_VERTICAL_PADDING;
|
return SymmetricSorter.INTERNODE_VERTICAL_PADDING;
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,16 +12,16 @@ const rootedTreeSet = require('./RootedTreeSet').default;
|
|||||||
const symmetricSorter = require('./SymmetricSorter').default;
|
const symmetricSorter = require('./SymmetricSorter').default;
|
||||||
|
|
||||||
export const Layout = {
|
export const Layout = {
|
||||||
AbstractBasicSorter: abstractBasicSorter,
|
AbstractBasicSorter: abstractBasicSorter,
|
||||||
BalancedSorter: balancedSorter,
|
BalancedSorter: balancedSorter,
|
||||||
ChangeEvent: changeEvent,
|
ChangeEvent: changeEvent,
|
||||||
ChildrenSorterStrategy: childrenSorterStrategy,
|
ChildrenSorterStrategy: childrenSorterStrategy,
|
||||||
EventBus: eventBus,
|
EventBus: eventBus,
|
||||||
EventBusDispatcher: eventBusDispatcher,
|
EventBusDispatcher: eventBusDispatcher,
|
||||||
GridSorter: gridSorter,
|
GridSorter: gridSorter,
|
||||||
LayoutManager: layoutManager,
|
LayoutManager: layoutManager,
|
||||||
Node: node,
|
Node: node,
|
||||||
OriginalLayout: originalLayout,
|
OriginalLayout: originalLayout,
|
||||||
RootedTreeSet: rootedTreeSet,
|
RootedTreeSet: rootedTreeSet,
|
||||||
SymmetricSorter: symmetricSorter,
|
SymmetricSorter: symmetricSorter,
|
||||||
};
|
};
|
||||||
|
@ -1,51 +1,50 @@
|
|||||||
const BootstrapDialog = require('./BootstrapDialog').default
|
const BootstrapDialog = require('./BootstrapDialog').default;
|
||||||
|
|
||||||
BootstrapDialog.Request = new Class({
|
BootstrapDialog.Request = new Class({
|
||||||
|
|
||||||
Extends: BootstrapDialog,
|
Extends: BootstrapDialog,
|
||||||
|
|
||||||
initialize: function(url, title, options) {
|
initialize(url, title, options) {
|
||||||
this.parent(title, options);
|
this.parent(title, options);
|
||||||
this.requestOptions = {};
|
this.requestOptions = {};
|
||||||
this.requestOptions.cache = false;
|
this.requestOptions.cache = false;
|
||||||
var me = this;
|
const me = this;
|
||||||
this.requestOptions.fail = function(xhr) {
|
this.requestOptions.fail = function (xhr) {
|
||||||
// Intercept form requests ...
|
// Intercept form requests ...
|
||||||
console.log("Failure:");
|
console.log('Failure:');
|
||||||
console.log(xhr);
|
console.log(xhr);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.requestOptions.success = function() {
|
this.requestOptions.success = function () {
|
||||||
// Intercept form requests ...
|
// Intercept form requests ...
|
||||||
var forms = me._native.find('form');
|
const forms = me._native.find('form');
|
||||||
_.each(forms, function(form) {
|
_.each(forms, (form) => {
|
||||||
$(form).on('submit', function(event) {
|
$(form).on('submit', (event) => {
|
||||||
// Intercept form ...
|
// Intercept form ...
|
||||||
me.requestOptions.url = form.action;
|
me.requestOptions.url = form.action;
|
||||||
me.requestOptions.method = form.method ? form.method : 'post';
|
me.requestOptions.method = form.method ? form.method : 'post';
|
||||||
$.ajax(me.requestOptions);
|
$.ajax(me.requestOptions);
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
return false;
|
return false;
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
this._native.find('.modal-body').load(url, function () {
|
|
||||||
me.acceptButton.unbind('click').click(function () {
|
|
||||||
submitDialogForm();
|
|
||||||
});
|
|
||||||
me._native.on('hidden.bs.modal', function () {
|
|
||||||
$(this).remove();
|
|
||||||
});
|
|
||||||
me.show();
|
|
||||||
});
|
});
|
||||||
},
|
});
|
||||||
|
};
|
||||||
|
|
||||||
onDialogShown: function() {
|
this._native.find('.modal-body').load(url, () => {
|
||||||
if (typeof(onDialogShown) == "function") {
|
me.acceptButton.unbind('click').click(() => {
|
||||||
onDialogShown();
|
submitDialogForm();
|
||||||
}
|
});
|
||||||
|
me._native.on('hidden.bs.modal', function () {
|
||||||
|
$(this).remove();
|
||||||
|
});
|
||||||
|
me.show();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onDialogShown() {
|
||||||
|
if (typeof (onDialogShown) === 'function') {
|
||||||
|
onDialogShown();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1,115 +1,115 @@
|
|||||||
const Options = require('../../Options').default;
|
const Options = require('../../Options').default;
|
||||||
|
|
||||||
const BootstrapDialog = new Class({
|
const BootstrapDialog = new Class({
|
||||||
Implements: Options,
|
Implements: Options,
|
||||||
|
|
||||||
options: {
|
options: {
|
||||||
cancelButton: false,
|
cancelButton: false,
|
||||||
closeButton: false,
|
closeButton: false,
|
||||||
acceptButton: true,
|
acceptButton: true,
|
||||||
removeButton:false,
|
removeButton: false,
|
||||||
errorMessage: false,
|
errorMessage: false,
|
||||||
onEventData:{}
|
onEventData: {},
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize: function (title, options) {
|
initialize(title, options) {
|
||||||
this.setOptions(options);
|
this.setOptions(options);
|
||||||
this.options.onEventData.dialog = this;
|
this.options.onEventData.dialog = this;
|
||||||
this._native = $('<div class="modal fade" tabindex="-1"></div>').append('<div class="modal-dialog"></div>');
|
this._native = $('<div class="modal fade" tabindex="-1"></div>').append('<div class="modal-dialog"></div>');
|
||||||
var content = $('<div class="modal-content"></div>');
|
const content = $('<div class="modal-content"></div>');
|
||||||
var header = this._buildHeader(title);
|
const header = this._buildHeader(title);
|
||||||
if (header) {
|
if (header) {
|
||||||
content.append(header);
|
content.append(header);
|
||||||
}
|
|
||||||
var body = $('<div class="modal-body"></div>');
|
|
||||||
if(this.options.errorMessage){
|
|
||||||
var error = $('<div class="alert alert-danger"></div>');
|
|
||||||
error.hide();
|
|
||||||
body.append(error);
|
|
||||||
}
|
|
||||||
content.append(body);
|
|
||||||
var footer = this._buildFooter();
|
|
||||||
if (footer) {
|
|
||||||
content.append(footer);
|
|
||||||
}
|
|
||||||
this._native.find(".modal-dialog").append(content);
|
|
||||||
this._native.on('hidden.bs.modal', function() {
|
|
||||||
$(this).remove();
|
|
||||||
});
|
|
||||||
this._native.on('shown.bs.modal', this.onDialogShown);
|
|
||||||
},
|
|
||||||
|
|
||||||
_buildFooter: function() {
|
|
||||||
var footer = null;
|
|
||||||
if (this.options.acceptButton || this.options.removeButton || this.options.cancelButton) {
|
|
||||||
footer = $('<div class="modal-footer" style="paddingTop:5;textAlign:center">');
|
|
||||||
}
|
|
||||||
if (this.options.acceptButton) {
|
|
||||||
this.acceptButton = $('<button type="button" class="btn btn-primary" id="acceptBtn" data-dismiss="modal">'+ $msg('ACCEPT') + '</button>');
|
|
||||||
footer.append(this.acceptButton);
|
|
||||||
this.acceptButton.unbind('click').on("click",this.options.onEventData, this.onAcceptClick)
|
|
||||||
}
|
|
||||||
if (this.options.removeButton) {
|
|
||||||
this.removeButton = $('<button type="button" class="btn btn-secondary" id="removeBtn" data-dismiss="modal">'+ $msg('REMOVE') +'</button>');
|
|
||||||
footer.append(this.removeButton);
|
|
||||||
this.removeButton.on('click', this.options.onEventData, this.onRemoveClick);
|
|
||||||
}
|
|
||||||
if (this.options.cancelButton) {
|
|
||||||
footer.append('<button type="button" class="btn btn-secondary" data-dismiss="modal">'+ $msg('CANCEL') +'</button>');
|
|
||||||
}
|
|
||||||
return footer;
|
|
||||||
},
|
|
||||||
|
|
||||||
_buildHeader: function(title) {
|
|
||||||
var header = null;
|
|
||||||
if (this.options.closeButton || title) {
|
|
||||||
header = $('<div class="modal-header"></div>');
|
|
||||||
}
|
|
||||||
if (this.options.closeButton) {
|
|
||||||
header.append(
|
|
||||||
'<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (title) {
|
|
||||||
header.append('<h2 class="modal-title">' + title + '</h2>');
|
|
||||||
}
|
|
||||||
return header;
|
|
||||||
},
|
|
||||||
|
|
||||||
onAcceptClick: function(event) {
|
|
||||||
throw "Unsupported operation";
|
|
||||||
},
|
|
||||||
|
|
||||||
onDialogShown: function() {},
|
|
||||||
onRemoveClick: function(event) {
|
|
||||||
throw "Unsupported operation";
|
|
||||||
},
|
|
||||||
|
|
||||||
show: function () {
|
|
||||||
this._native.modal();
|
|
||||||
},
|
|
||||||
|
|
||||||
setContent: function(content) {
|
|
||||||
var modalBody = this._native.find('.modal-body');
|
|
||||||
modalBody.append(content);
|
|
||||||
},
|
|
||||||
|
|
||||||
css: function(options){
|
|
||||||
this._native.find('.modal-dialog').css(options);
|
|
||||||
},
|
|
||||||
|
|
||||||
close: function() {
|
|
||||||
this._native.modal('hide');
|
|
||||||
},
|
|
||||||
|
|
||||||
alertError: function(message){
|
|
||||||
this._native.find('.alert-danger').text(message);
|
|
||||||
this._native.find('.alert-danger').show();
|
|
||||||
},
|
|
||||||
|
|
||||||
cleanError: function(){
|
|
||||||
this._native.find('.alert-danger').hide();
|
|
||||||
}
|
}
|
||||||
|
const body = $('<div class="modal-body"></div>');
|
||||||
|
if (this.options.errorMessage) {
|
||||||
|
const error = $('<div class="alert alert-danger"></div>');
|
||||||
|
error.hide();
|
||||||
|
body.append(error);
|
||||||
|
}
|
||||||
|
content.append(body);
|
||||||
|
const footer = this._buildFooter();
|
||||||
|
if (footer) {
|
||||||
|
content.append(footer);
|
||||||
|
}
|
||||||
|
this._native.find('.modal-dialog').append(content);
|
||||||
|
this._native.on('hidden.bs.modal', function () {
|
||||||
|
$(this).remove();
|
||||||
|
});
|
||||||
|
this._native.on('shown.bs.modal', this.onDialogShown);
|
||||||
|
},
|
||||||
|
|
||||||
|
_buildFooter() {
|
||||||
|
let footer = null;
|
||||||
|
if (this.options.acceptButton || this.options.removeButton || this.options.cancelButton) {
|
||||||
|
footer = $('<div class="modal-footer" style="paddingTop:5;textAlign:center">');
|
||||||
|
}
|
||||||
|
if (this.options.acceptButton) {
|
||||||
|
this.acceptButton = $(`<button type="button" class="btn btn-primary" id="acceptBtn" data-dismiss="modal">${$msg('ACCEPT')}</button>`);
|
||||||
|
footer.append(this.acceptButton);
|
||||||
|
this.acceptButton.unbind('click').on('click', this.options.onEventData, this.onAcceptClick);
|
||||||
|
}
|
||||||
|
if (this.options.removeButton) {
|
||||||
|
this.removeButton = $(`<button type="button" class="btn btn-secondary" id="removeBtn" data-dismiss="modal">${$msg('REMOVE')}</button>`);
|
||||||
|
footer.append(this.removeButton);
|
||||||
|
this.removeButton.on('click', this.options.onEventData, this.onRemoveClick);
|
||||||
|
}
|
||||||
|
if (this.options.cancelButton) {
|
||||||
|
footer.append(`<button type="button" class="btn btn-secondary" data-dismiss="modal">${$msg('CANCEL')}</button>`);
|
||||||
|
}
|
||||||
|
return footer;
|
||||||
|
},
|
||||||
|
|
||||||
|
_buildHeader(title) {
|
||||||
|
let header = null;
|
||||||
|
if (this.options.closeButton || title) {
|
||||||
|
header = $('<div class="modal-header"></div>');
|
||||||
|
}
|
||||||
|
if (this.options.closeButton) {
|
||||||
|
header.append(
|
||||||
|
'<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (title) {
|
||||||
|
header.append(`<h2 class="modal-title">${title}</h2>`);
|
||||||
|
}
|
||||||
|
return header;
|
||||||
|
},
|
||||||
|
|
||||||
|
onAcceptClick(event) {
|
||||||
|
throw 'Unsupported operation';
|
||||||
|
},
|
||||||
|
|
||||||
|
onDialogShown() {},
|
||||||
|
onRemoveClick(event) {
|
||||||
|
throw 'Unsupported operation';
|
||||||
|
},
|
||||||
|
|
||||||
|
show() {
|
||||||
|
this._native.modal();
|
||||||
|
},
|
||||||
|
|
||||||
|
setContent(content) {
|
||||||
|
const modalBody = this._native.find('.modal-body');
|
||||||
|
modalBody.append(content);
|
||||||
|
},
|
||||||
|
|
||||||
|
css(options) {
|
||||||
|
this._native.find('.modal-dialog').css(options);
|
||||||
|
},
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this._native.modal('hide');
|
||||||
|
},
|
||||||
|
|
||||||
|
alertError(message) {
|
||||||
|
this._native.find('.alert-danger').text(message);
|
||||||
|
this._native.find('.alert-danger').show();
|
||||||
|
},
|
||||||
|
|
||||||
|
cleanError() {
|
||||||
|
this._native.find('.alert-danger').hide();
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default BootstrapDialog;
|
export default BootstrapDialog;
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -15,96 +15,158 @@
|
|||||||
* Might be useful, when you want to pass some other data to your handler
|
* Might be useful, when you want to pass some other data to your handler
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function(jQuery){
|
(function (jQuery) {
|
||||||
|
jQuery.hotkeys = {
|
||||||
|
version: '0.8',
|
||||||
|
|
||||||
jQuery.hotkeys = {
|
specialKeys: {
|
||||||
version: "0.8",
|
8: 'backspace',
|
||||||
|
9: 'tab',
|
||||||
|
10: 'return',
|
||||||
|
13: 'enter',
|
||||||
|
16: 'shift',
|
||||||
|
17: 'ctrl',
|
||||||
|
18: 'alt',
|
||||||
|
19: 'pause',
|
||||||
|
20: 'capslock',
|
||||||
|
27: 'esc',
|
||||||
|
32: 'space',
|
||||||
|
33: 'pageup',
|
||||||
|
34: 'pagedown',
|
||||||
|
35: 'end',
|
||||||
|
36: 'home',
|
||||||
|
37: 'left',
|
||||||
|
38: 'up',
|
||||||
|
39: 'right',
|
||||||
|
40: 'down',
|
||||||
|
45: 'insert',
|
||||||
|
46: 'del',
|
||||||
|
96: '0',
|
||||||
|
97: '1',
|
||||||
|
98: '2',
|
||||||
|
99: '3',
|
||||||
|
100: '4',
|
||||||
|
101: '5',
|
||||||
|
102: '6',
|
||||||
|
103: '7',
|
||||||
|
104: '8',
|
||||||
|
105: '9',
|
||||||
|
106: '*',
|
||||||
|
107: '+',
|
||||||
|
109: '-',
|
||||||
|
110: '.',
|
||||||
|
111: '/',
|
||||||
|
112: 'f1',
|
||||||
|
113: 'f2',
|
||||||
|
114: 'f3',
|
||||||
|
115: 'f4',
|
||||||
|
116: 'f5',
|
||||||
|
117: 'f6',
|
||||||
|
118: 'f7',
|
||||||
|
119: 'f8',
|
||||||
|
120: 'f9',
|
||||||
|
121: 'f10',
|
||||||
|
122: 'f11',
|
||||||
|
123: 'f12',
|
||||||
|
144: 'numlock',
|
||||||
|
145: 'scroll',
|
||||||
|
186: ';',
|
||||||
|
191: '/',
|
||||||
|
220: '\\',
|
||||||
|
222: "'",
|
||||||
|
224: 'meta',
|
||||||
|
},
|
||||||
|
|
||||||
specialKeys: {
|
shiftNums: {
|
||||||
8: "backspace", 9: "tab", 10: "return", 13: "enter", 16: "shift", 17: "ctrl", 18: "alt", 19: "pause",
|
'`': '~',
|
||||||
20: "capslock", 27: "esc", 32: "space", 33: "pageup", 34: "pagedown", 35: "end", 36: "home",
|
1: '!',
|
||||||
37: "left", 38: "up", 39: "right", 40: "down", 45: "insert", 46: "del",
|
2: '@',
|
||||||
96: "0", 97: "1", 98: "2", 99: "3", 100: "4", 101: "5", 102: "6", 103: "7",
|
3: '#',
|
||||||
104: "8", 105: "9", 106: "*", 107: "+", 109: "-", 110: ".", 111 : "/",
|
4: '$',
|
||||||
112: "f1", 113: "f2", 114: "f3", 115: "f4", 116: "f5", 117: "f6", 118: "f7", 119: "f8",
|
5: '%',
|
||||||
120: "f9", 121: "f10", 122: "f11", 123: "f12", 144: "numlock", 145: "scroll", 186: ";", 191: "/",
|
6: '^',
|
||||||
220: "\\", 222: "'", 224: "meta"
|
7: '&',
|
||||||
},
|
8: '*',
|
||||||
|
9: '(',
|
||||||
|
0: ')',
|
||||||
|
'-': '_',
|
||||||
|
'=': '+',
|
||||||
|
';': ': ',
|
||||||
|
"'": '"',
|
||||||
|
',': '<',
|
||||||
|
'.': '>',
|
||||||
|
'/': '?',
|
||||||
|
'\\': '|',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
shiftNums: {
|
function keyHandler(handleObj) {
|
||||||
"`": "~", "1": "!", "2": "@", "3": "#", "4": "$", "5": "%", "6": "^", "7": "&",
|
if (typeof handleObj.data === 'string') {
|
||||||
"8": "*", "9": "(", "0": ")", "-": "_", "=": "+", ";": ": ", "'": "\"", ",": "<",
|
handleObj.data = { keys: handleObj.data };
|
||||||
".": ">", "/": "?", "\\": "|"
|
}
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function keyHandler( handleObj ) {
|
// Only care when a possible input has been specified
|
||||||
if ( typeof handleObj.data === "string" ) {
|
if (!handleObj.data || !handleObj.data.keys || typeof handleObj.data.keys !== 'string') {
|
||||||
handleObj.data = { keys: handleObj.data };
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only care when a possible input has been specified
|
const origHandler = handleObj.handler;
|
||||||
if ( !handleObj.data || !handleObj.data.keys || typeof handleObj.data.keys !== "string" ) {
|
const keys = handleObj.data.keys.toLowerCase().split(' ');
|
||||||
return;
|
const textAcceptingInputTypes = ['text', 'password', 'number', 'email', 'url', 'range', 'date', 'month', 'week', 'time', 'datetime', 'datetime-local', 'search', 'color', 'tel'];
|
||||||
}
|
|
||||||
|
|
||||||
var origHandler = handleObj.handler,
|
handleObj.handler = function (event) {
|
||||||
keys = handleObj.data.keys.toLowerCase().split(" "),
|
// Don't fire in text-accepting inputs that we didn't directly bind to
|
||||||
textAcceptingInputTypes = ["text", "password", "number", "email", "url", "range", "date", "month", "week", "time", "datetime", "datetime-local", "search", "color", "tel"];
|
if (this !== event.target && (/textarea|select/i.test(event.target.nodeName)
|
||||||
|
|| jQuery.inArray(event.target.type, textAcceptingInputTypes) > -1)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
handleObj.handler = function( event ) {
|
const special = jQuery.hotkeys.specialKeys[event.keyCode];
|
||||||
// Don't fire in text-accepting inputs that we didn't directly bind to
|
const character = String.fromCharCode(event.which).toLowerCase();
|
||||||
if ( this !== event.target && (/textarea|select/i.test( event.target.nodeName ) ||
|
let modif = ''; const
|
||||||
jQuery.inArray(event.target.type, textAcceptingInputTypes) > -1 ) ) {
|
possible = {};
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var special = jQuery.hotkeys.specialKeys[ event.keyCode ],
|
// check combinations (alt|ctrl|shift+anything)
|
||||||
character = String.fromCharCode( event.which ).toLowerCase(),
|
if (event.altKey && special !== 'alt') {
|
||||||
modif = "", possible = {};
|
modif += 'alt+';
|
||||||
|
}
|
||||||
|
|
||||||
// check combinations (alt|ctrl|shift+anything)
|
if (event.ctrlKey && special !== 'ctrl') {
|
||||||
if ( event.altKey && special !== "alt" ) {
|
modif += 'ctrl+';
|
||||||
modif += "alt+";
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ( event.ctrlKey && special !== "ctrl" ) {
|
// TODO: Need to make sure this works consistently across platforms
|
||||||
modif += "ctrl+";
|
if (event.metaKey && !event.ctrlKey && special !== 'meta') {
|
||||||
}
|
modif += 'meta+';
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Need to make sure this works consistently across platforms
|
if (event.shiftKey && special !== 'shift') {
|
||||||
if ( event.metaKey && !event.ctrlKey && special !== "meta" ) {
|
modif += 'shift+';
|
||||||
modif += "meta+";
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ( event.shiftKey && special !== "shift" ) {
|
if (special) {
|
||||||
modif += "shift+";
|
possible[modif + special] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( special ) {
|
if (character) {
|
||||||
possible[ modif + special ] = true;
|
possible[modif + character] = true;
|
||||||
}
|
possible[modif + jQuery.hotkeys.shiftNums[character]] = true;
|
||||||
|
|
||||||
if ( character ) {
|
// "$" can be triggered as "Shift+4" or "Shift+$" or just "$"
|
||||||
possible[ modif + character ] = true;
|
if (modif === 'shift+') {
|
||||||
possible[ modif + jQuery.hotkeys.shiftNums[ character ] ] = true;
|
possible[jQuery.hotkeys.shiftNums[character]] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// "$" can be triggered as "Shift+4" or "Shift+$" or just "$"
|
for (let i = 0, l = keys.length; i < l; i++) {
|
||||||
if ( modif === "shift+" ) {
|
if (possible[keys[i]]) {
|
||||||
possible[ jQuery.hotkeys.shiftNums[ character ] ] = true;
|
return origHandler.apply(this, arguments);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
for ( var i = 0, l = keys.length; i < l; i++ ) {
|
jQuery.each(['keydown', 'keyup', 'keypress'], function () {
|
||||||
if ( possible[ keys[i] ] ) {
|
jQuery.event.special[this] = { add: keyHandler };
|
||||||
return origHandler.apply( this, arguments );
|
});
|
||||||
}
|
}(this.jQuery));
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
jQuery.each([ "keydown", "keyup", "keypress" ], function() {
|
|
||||||
jQuery.event.special[ this ] = { add: keyHandler };
|
|
||||||
});
|
|
||||||
|
|
||||||
})( this.jQuery );
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -5,4 +5,8 @@
|
|||||||
*
|
*
|
||||||
* Requires: jQuery 1.2.2+
|
* Requires: jQuery 1.2.2+
|
||||||
*/
|
*/
|
||||||
!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?module.exports=a:a(jQuery)}(function(a){function b(b){var g=b||window.event,h=i.call(arguments,1),j=0,l=0,m=0,n=0,o=0,p=0;if(b=a.event.fix(g),b.type="mousewheel","detail"in g&&(m=-1*g.detail),"wheelDelta"in g&&(m=g.wheelDelta),"wheelDeltaY"in g&&(m=g.wheelDeltaY),"wheelDeltaX"in g&&(l=-1*g.wheelDeltaX),"axis"in g&&g.axis===g.HORIZONTAL_AXIS&&(l=-1*m,m=0),j=0===m?l:m,"deltaY"in g&&(m=-1*g.deltaY,j=m),"deltaX"in g&&(l=g.deltaX,0===m&&(j=-1*l)),0!==m||0!==l){if(1===g.deltaMode){var q=a.data(this,"mousewheel-line-height");j*=q,m*=q,l*=q}else if(2===g.deltaMode){var r=a.data(this,"mousewheel-page-height");j*=r,m*=r,l*=r}if(n=Math.max(Math.abs(m),Math.abs(l)),(!f||f>n)&&(f=n,d(g,n)&&(f/=40)),d(g,n)&&(j/=40,l/=40,m/=40),j=Math[j>=1?"floor":"ceil"](j/f),l=Math[l>=1?"floor":"ceil"](l/f),m=Math[m>=1?"floor":"ceil"](m/f),k.settings.normalizeOffset&&this.getBoundingClientRect){var s=this.getBoundingClientRect();o=b.clientX-s.left,p=b.clientY-s.top}return b.deltaX=l,b.deltaY=m,b.deltaFactor=f,b.offsetX=o,b.offsetY=p,b.deltaMode=0,h.unshift(b,j,l,m),e&&clearTimeout(e),e=setTimeout(c,200),(a.event.dispatch||a.event.handle).apply(this,h)}}function c(){f=null}function d(a,b){return k.settings.adjustOldDeltas&&"mousewheel"===a.type&&b%120===0}var e,f,g=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],h="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],i=Array.prototype.slice;if(a.event.fixHooks)for(var j=g.length;j;)a.event.fixHooks[g[--j]]=a.event.mouseHooks;var k=a.event.special.mousewheel={version:"3.1.11",setup:function(){if(this.addEventListener)for(var c=h.length;c;)this.addEventListener(h[--c],b,!1);else this.onmousewheel=b;a.data(this,"mousewheel-line-height",k.getLineHeight(this)),a.data(this,"mousewheel-page-height",k.getPageHeight(this))},teardown:function(){if(this.removeEventListener)for(var c=h.length;c;)this.removeEventListener(h[--c],b,!1);else this.onmousewheel=null;a.removeData(this,"mousewheel-line-height"),a.removeData(this,"mousewheel-page-height")},getLineHeight:function(b){var c=a(b)["offsetParent"in a.fn?"offsetParent":"parent"]();return c.length||(c=a("body")),parseInt(c.css("fontSize"),10)},getPageHeight:function(b){return a(b).height()},settings:{adjustOldDeltas:!0,normalizeOffset:!0}};a.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})});
|
!(function (a) { typeof define === 'function' && define.amd ? define(['jquery'], a) : typeof exports === 'object' ? module.exports = a : a(jQuery); }((a) => {
|
||||||
|
function b(b) { const g = b || window.event; const h = i.call(arguments, 1); let j = 0; let l = 0; let m = 0; let n = 0; let o = 0; let p = 0; if (b = a.event.fix(g), b.type = 'mousewheel', 'detail' in g && (m = -1 * g.detail), 'wheelDelta' in g && (m = g.wheelDelta), 'wheelDeltaY' in g && (m = g.wheelDeltaY), 'wheelDeltaX' in g && (l = -1 * g.wheelDeltaX), 'axis' in g && g.axis === g.HORIZONTAL_AXIS && (l = -1 * m, m = 0), j = m === 0 ? l : m, 'deltaY' in g && (m = -1 * g.deltaY, j = m), 'deltaX' in g && (l = g.deltaX, m === 0 && (j = -1 * l)), m !== 0 || l !== 0) { if (g.deltaMode === 1) { const q = a.data(this, 'mousewheel-line-height'); j *= q, m *= q, l *= q; } else if (g.deltaMode === 2) { const r = a.data(this, 'mousewheel-page-height'); j *= r, m *= r, l *= r; } if (n = Math.max(Math.abs(m), Math.abs(l)), (!f || f > n) && (f = n, d(g, n) && (f /= 40)), d(g, n) && (j /= 40, l /= 40, m /= 40), j = Math[j >= 1 ? 'floor' : 'ceil'](j / f), l = Math[l >= 1 ? 'floor' : 'ceil'](l / f), m = Math[m >= 1 ? 'floor' : 'ceil'](m / f), k.settings.normalizeOffset && this.getBoundingClientRect) { const s = this.getBoundingClientRect(); o = b.clientX - s.left, p = b.clientY - s.top; } return b.deltaX = l, b.deltaY = m, b.deltaFactor = f, b.offsetX = o, b.offsetY = p, b.deltaMode = 0, h.unshift(b, j, l, m), e && clearTimeout(e), e = setTimeout(c, 200), (a.event.dispatch || a.event.handle).apply(this, h); } } function c() { f = null; } function d(a, b) { return k.settings.adjustOldDeltas && a.type === 'mousewheel' && b % 120 === 0; } let e; let f; const g = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll']; const h = 'onwheel' in document || document.documentMode >= 9 ? ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll']; var i = Array.prototype.slice; if (a.event.fixHooks) for (let j = g.length; j;)a.event.fixHooks[g[--j]] = a.event.mouseHooks; var k = a.event.special.mousewheel = {
|
||||||
|
version: '3.1.11', setup() { if (this.addEventListener) for (let c = h.length; c;) this.addEventListener(h[--c], b, !1); else this.onmousewheel = b; a.data(this, 'mousewheel-line-height', k.getLineHeight(this)), a.data(this, 'mousewheel-page-height', k.getPageHeight(this)); }, teardown() { if (this.removeEventListener) for (let c = h.length; c;) this.removeEventListener(h[--c], b, !1); else this.onmousewheel = null; a.removeData(this, 'mousewheel-line-height'), a.removeData(this, 'mousewheel-page-height'); }, getLineHeight(b) { let c = a(b)['offsetParent' in a.fn ? 'offsetParent' : 'parent'](); return c.length || (c = a('body')), parseInt(c.css('fontSize'), 10); }, getPageHeight(b) { return a(b).height(); }, settings: { adjustOldDeltas: !0, normalizeOffset: !0 },
|
||||||
|
}; a.fn.extend({ mousewheel(a) { return a ? this.bind('mousewheel', a) : this.trigger('mousewheel'); }, unmousewheel(a) { return this.unbind('mousewheel', a); } });
|
||||||
|
}));
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@ -16,61 +16,256 @@
|
|||||||
...
|
...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function(){this.MooTools={version:"1.4.5",build:"ab8ea8824dc3b24b6666867a2c4ed58ebb762cf0"};var o=this.typeOf=function(i){if(i==null){return"null";}if(i.$family!=null){return i.$family();
|
(function () {
|
||||||
}if(i.nodeName){if(i.nodeType==1){return"element";}if(i.nodeType==3){return(/\S/).test(i.nodeValue)?"textnode":"whitespace";}}else{if(typeof i.length=="number"){if(i.callee){return"arguments";
|
this.MooTools = { version: '1.4.5', build: 'ab8ea8824dc3b24b6666867a2c4ed58ebb762cf0' }; const o = this.typeOf = function (i) {
|
||||||
}if("item" in i){return"collection";}}}return typeof i;};var j=this.instanceOf=function(t,i){if(t==null){return false;}var s=t.$constructor||t.constructor;
|
if (i == null) { return 'null'; } if (i.$family != null) {
|
||||||
while(s){if(s===i){return true;}s=s.parent;}if(!t.hasOwnProperty){return false;}return t instanceof i;};var f=this.Function;var p=true;for(var k in {toString:1}){p=null;
|
return i.$family();
|
||||||
}if(p){p=["hasOwnProperty","valueOf","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","constructor"];}f.prototype.overloadSetter=function(s){var i=this;
|
} if (i.nodeName) { if (i.nodeType == 1) { return 'element'; } if (i.nodeType == 3) { return (/\S/).test(i.nodeValue) ? 'textnode' : 'whitespace'; } } else if (typeof i.length === 'number') {
|
||||||
return function(u,t){if(u==null){return this;}if(s||typeof u!="string"){for(var v in u){i.call(this,v,u[v]);}if(p){for(var w=p.length;w--;){v=p[w];if(u.hasOwnProperty(v)){i.call(this,v,u[v]);
|
if (i.callee) {
|
||||||
}}}}else{i.call(this,u,t);}return this;};};f.prototype.overloadGetter=function(s){var i=this;return function(u){var v,t;if(typeof u!="string"){v=u;}else{if(arguments.length>1){v=arguments;
|
return 'arguments';
|
||||||
}else{if(s){v=[u];}}}if(v){t={};for(var w=0;w<v.length;w++){t[v[w]]=i.call(this,v[w]);}}else{t=i.call(this,u);}return t;};};f.prototype.extend=function(i,s){this[i]=s;
|
} if ('item' in i) { return 'collection'; }
|
||||||
}.overloadSetter();f.prototype.implement=function(i,s){this.prototype[i]=s;}.overloadSetter();var n=Array.prototype.slice;f.from=function(i){return(o(i)=="function")?i:function(){return i;
|
} return typeof i;
|
||||||
};};Array.from=function(i){if(i==null){return[];}return(a.isEnumerable(i)&&typeof i!="string")?(o(i)=="array")?i:n.call(i):[i];};Number.from=function(s){var i=parseFloat(s);
|
}; const j = this.instanceOf = function (t, i) {
|
||||||
return isFinite(i)?i:null;};String.from=function(i){return i+"";};f.implement({hide:function(){this.$hidden=true;return this;},protect:function(){this.$protected=true;
|
if (t == null) { return false; } let s = t.$constructor || t.constructor;
|
||||||
return this;}});var a=this.Type=function(u,t){if(u){var s=u.toLowerCase();var i=function(v){return(o(v)==s);};a["is"+u]=i;if(t!=null){t.prototype.$family=(function(){return s;
|
while (s) { if (s === i) { return true; }s = s.parent; } if (!t.hasOwnProperty) { return false; } return t instanceof i;
|
||||||
}).hide();}}if(t==null){return null;}t.extend(this);t.$constructor=a;t.prototype.$constructor=t;return t;};var e=Object.prototype.toString;a.isEnumerable=function(i){return(i!=null&&typeof i.length=="number"&&e.call(i)!="[object Function]");
|
}; const f = this.Function; let p = true; for (const k in { toString: 1 }) {
|
||||||
};var q={};var r=function(i){var s=o(i.prototype);return q[s]||(q[s]=[]);};var b=function(t,x){if(x&&x.$hidden){return;}var s=r(this);for(var u=0;u<s.length;
|
p = null;
|
||||||
u++){var w=s[u];if(o(w)=="type"){b.call(w,t,x);}else{w.call(this,t,x);}}var v=this.prototype[t];if(v==null||!v.$protected){this.prototype[t]=x;}if(this[t]==null&&o(x)=="function"){m.call(this,t,function(i){return x.apply(i,n.call(arguments,1));
|
} if (p) { p = ['hasOwnProperty', 'valueOf', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'constructor']; }f.prototype.overloadSetter = function (s) {
|
||||||
});}};var m=function(i,t){if(t&&t.$hidden){return;}var s=this[i];if(s==null||!s.$protected){this[i]=t;}};a.implement({implement:b.overloadSetter(),extend:m.overloadSetter(),alias:function(i,s){b.call(this,i,this.prototype[s]);
|
const i = this;
|
||||||
}.overloadSetter(),mirror:function(i){r(this).push(i);return this;}});new a("Type",a);var d=function(s,x,v){var u=(x!=Object),B=x.prototype;if(u){x=new a(s,x);
|
return function (u, t) {
|
||||||
}for(var y=0,w=v.length;y<w;y++){var C=v[y],A=x[C],z=B[C];if(A){A.protect();}if(u&&z){x.implement(C,z.protect());}}if(u){var t=B.propertyIsEnumerable(v[0]);
|
if (u == null) { return this; } if (s || typeof u !== 'string') {
|
||||||
x.forEachMethod=function(G){if(!t){for(var F=0,D=v.length;F<D;F++){G.call(B,B[v[F]],v[F]);}}for(var E in B){G.call(B,B[E],E);}};}return d;};d("String",String,["charAt","charCodeAt","concat","indexOf","lastIndexOf","match","quote","replace","search","slice","split","substr","substring","trim","toLowerCase","toUpperCase"])("Array",Array,["pop","push","reverse","shift","sort","splice","unshift","concat","join","slice","indexOf","lastIndexOf","filter","forEach","every","map","some","reduce","reduceRight"])("Number",Number,["toExponential","toFixed","toLocaleString","toPrecision"])("Function",f,["apply","call","bind"])("RegExp",RegExp,["exec","test"])("Object",Object,["create","defineProperty","defineProperties","keys","getPrototypeOf","getOwnPropertyDescriptor","getOwnPropertyNames","preventExtensions","isExtensible","seal","isSealed","freeze","isFrozen"])("Date",Date,["now"]);
|
for (var v in u) { i.call(this, v, u[v]); } if (p) {
|
||||||
Object.extend=m.overloadSetter();Date.extend("now",function(){return +(new Date);});new a("Boolean",Boolean);Number.prototype.$family=function(){return isFinite(this)?"number":"null";
|
for (let w = p.length; w--;) {
|
||||||
}.hide();Number.extend("random",function(s,i){return Math.floor(Math.random()*(i-s+1)+s);});var g=Object.prototype.hasOwnProperty;Object.extend("forEach",function(i,t,u){for(var s in i){if(g.call(i,s)){t.call(u,i[s],s,i);
|
v = p[w]; if (u.hasOwnProperty(v)) {
|
||||||
}}});Object.each=Object.forEach;Array.implement({forEach:function(u,v){for(var t=0,s=this.length;t<s;t++){if(t in this){u.call(v,this[t],t,this);}}},each:function(i,s){Array.forEach(this,i,s);
|
i.call(this, v, u[v]);
|
||||||
return this;}});var l=function(i){switch(o(i)){case"array":return i.clone();case"object":return Object.clone(i);default:return i;}};Array.implement("clone",function(){var s=this.length,t=new Array(s);
|
}
|
||||||
while(s--){t[s]=l(this[s]);}return t;});var h=function(s,i,t){switch(o(t)){case"object":if(o(s[i])=="object"){Object.merge(s[i],t);}else{s[i]=Object.clone(t);
|
}
|
||||||
}break;case"array":s[i]=t.clone();break;default:s[i]=t;}return s;};Object.extend({merge:function(z,u,t){if(o(u)=="string"){return h(z,u,t);}for(var y=1,s=arguments.length;
|
}
|
||||||
y<s;y++){var w=arguments[y];for(var x in w){h(z,x,w[x]);}}return z;},clone:function(i){var t={};for(var s in i){t[s]=l(i[s]);}return t;},append:function(w){for(var v=1,t=arguments.length;
|
} else { i.call(this, u, t); } return this;
|
||||||
v<t;v++){var s=arguments[v]||{};for(var u in s){w[u]=s[u];}}return w;}});["Object","WhiteSpace","TextNode","Collection","Arguments"].each(function(i){new a(i);
|
};
|
||||||
});var c=Date.now();String.extend("uniqueID",function(){return(c++).toString(36);});})();Array.implement({every:function(c,d){for(var b=0,a=this.length>>>0;
|
}; f.prototype.overloadGetter = function (s) {
|
||||||
b<a;b++){if((b in this)&&!c.call(d,this[b],b,this)){return false;}}return true;},filter:function(d,f){var c=[];for(var e,b=0,a=this.length>>>0;b<a;b++){if(b in this){e=this[b];
|
const i = this; return function (u) {
|
||||||
if(d.call(f,e,b,this)){c.push(e);}}}return c;},indexOf:function(c,d){var b=this.length>>>0;for(var a=(d<0)?Math.max(0,b+d):d||0;a<b;a++){if(this[a]===c){return a;
|
let v; let t; if (typeof u !== 'string') { v = u; } else if (arguments.length > 1) {
|
||||||
}}return -1;},map:function(c,e){var d=this.length>>>0,b=Array(d);for(var a=0;a<d;a++){if(a in this){b[a]=c.call(e,this[a],a,this);}}return b;},some:function(c,d){for(var b=0,a=this.length>>>0;
|
v = arguments;
|
||||||
b<a;b++){if((b in this)&&c.call(d,this[b],b,this)){return true;}}return false;},clean:function(){return this.filter(function(a){return a!=null;});},invoke:function(a){var b=Array.slice(arguments,1);
|
} else if (s) { v = [u]; } if (v) { t = {}; for (let w = 0; w < v.length; w++) { t[v[w]] = i.call(this, v[w]); } } else { t = i.call(this, u); } return t;
|
||||||
return this.map(function(c){return c[a].apply(c,b);});},associate:function(c){var d={},b=Math.min(this.length,c.length);for(var a=0;a<b;a++){d[c[a]]=this[a];
|
};
|
||||||
}return d;},link:function(c){var a={};for(var e=0,b=this.length;e<b;e++){for(var d in c){if(c[d](this[e])){a[d]=this[e];delete c[d];break;}}}return a;},contains:function(a,b){return this.indexOf(a,b)!=-1;
|
}; f.prototype.extend = function (i, s) {
|
||||||
},append:function(a){this.push.apply(this,a);return this;},getLast:function(){return(this.length)?this[this.length-1]:null;},getRandom:function(){return(this.length)?this[Number.random(0,this.length-1)]:null;
|
this[i] = s;
|
||||||
},include:function(a){if(!this.contains(a)){this.push(a);}return this;},combine:function(c){for(var b=0,a=c.length;b<a;b++){this.include(c[b]);}return this;
|
}.overloadSetter(); f.prototype.implement = function (i, s) { this.prototype[i] = s; }.overloadSetter(); const n = Array.prototype.slice; f.from = function (i) {
|
||||||
},erase:function(b){for(var a=this.length;a--;){if(this[a]===b){this.splice(a,1);}}return this;},empty:function(){this.length=0;return this;},flatten:function(){var d=[];
|
return (o(i) == 'function') ? i : function () {
|
||||||
for(var b=0,a=this.length;b<a;b++){var c=typeOf(this[b]);if(c=="null"){continue;}d=d.concat((c=="array"||c=="collection"||c=="arguments"||instanceOf(this[b],Array))?Array.flatten(this[b]):this[b]);
|
return i;
|
||||||
}return d;},pick:function(){for(var b=0,a=this.length;b<a;b++){if(this[b]!=null){return this[b];}}return null;},rgbToHex:function(d){if(this.length<3){return null;}if(this.length==4&&this[3]==0&&!d){return"transparent";
|
};
|
||||||
}var b=[];for(var a=0;a<3;a++){var c=(this[a]-0).toString(16);b.push((c.length==1)?"0"+c:c);}return(d)?b:"#"+b.join("");}});String.implement({test:function(a,b){return((typeOf(a)=="regexp")?a:new RegExp(""+a,b)).test(this);
|
}; Array.from = function (i) { if (i == null) { return []; } return (a.isEnumerable(i) && typeof i !== 'string') ? (o(i) == 'array') ? i : n.call(i) : [i]; }; Number.from = function (s) {
|
||||||
},contains:function(a,b){return(b)?(b+this+b).indexOf(b+a+b)>-1:String(this).indexOf(a)>-1;},trim:function(){return String(this).replace(/^\s+|\s+$/g,"");
|
const i = parseFloat(s);
|
||||||
},clean:function(){return String(this).replace(/\s+/g," ").trim();},camelCase:function(){return String(this).replace(/-\D/g,function(a){return a.charAt(1).toUpperCase();
|
return isFinite(i) ? i : null;
|
||||||
});},hyphenate:function(){return String(this).replace(/[A-Z]/g,function(a){return("-"+a.charAt(0).toLowerCase());});},capitalize:function(){return String(this).replace(/\b[a-z]/g,function(a){return a.toUpperCase();
|
}; String.from = function (i) { return `${i}`; }; f.implement({
|
||||||
});},escapeRegExp:function(){return String(this).replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1");},rgbToHex:function(b){var a=String(this).match(/\d{1,3}/g);
|
hide() { this.$hidden = true; return this; },
|
||||||
return(a)?a.rgbToHex(b):null;},substitute:function(a,b){return String(this).replace(b||(/\\?\{([^{}]+)\}/g),function(d,c){if(d.charAt(0)=="\\"){return d.slice(1);
|
protect() {
|
||||||
}return(a[c]!=null)?a[c]:"";});}});
|
this.$protected = true;
|
||||||
Function.implement({bind:function(e){var a=this,b=arguments.length>1?Array.slice(arguments,1):null,d=function(){};var c=function(){var g=e,h=arguments.length;if(this instanceof c){d.prototype=a.prototype;g=new d;}var f=(!b&&!h)?a.call(g):a.apply(g,b&&h?b.concat(Array.slice(arguments)):b||arguments);return g==e?f:g;};return c;},pass:function(b,c){var a=this;if(b!=null){b=Array.from(b);}return function(){return a.apply(c,b||arguments);};},delay:function(b,c,a){return setTimeout(this.pass((a==null?[]:a),c),b);},});
|
return this;
|
||||||
Number.alias("each","times");(function(b){var a={};b.each(function(c){if(!Number[c]){a[c]=function(){return Math[c].apply(null,[this].concat(Array.from(arguments)));
|
},
|
||||||
};}});Number.implement(a);})(["abs","acos","asin","atan","atan2","ceil","cos","exp","floor","log","max","min","pow","sin","sqrt","tan"]);(function(){var a=this.Class=new Type("Class",function(h){if(instanceOf(h,Function)){h={initialize:h};
|
}); var a = this.Type = function (u, t) {
|
||||||
}var g=function(){e(this);if(g.$prototyping){return this;}this.$caller=null;var i=(this.initialize)?this.initialize.apply(this,arguments):this;this.$caller=this.caller=null;
|
if (u) {
|
||||||
return i;}.extend(this).implement(h);g.$constructor=a;g.prototype.$constructor=g;g.prototype.parent=c;return g;});var c=function(){if(!this.$caller){throw new Error('The method "parent" cannot be called.');
|
const s = u.toLowerCase(); const i = function (v) { return (o(v) == s); }; a[`is${u}`] = i; if (t != null) {
|
||||||
}var g=this.$caller.$name,h=this.$caller.$owner.parent,i=(h)?h.prototype[g]:null;if(!i){throw new Error('The method "'+g+'" has no parent.');}return i.apply(this,arguments);
|
t.prototype.$family = (function () {
|
||||||
};var e=function(g){for(var h in g){var j=g[h];switch(typeOf(j)){case"object":var i=function(){};i.prototype=j;g[h]=e(new i);break;case"array":g[h]=j.clone();
|
return s;
|
||||||
break;}}return g;};var b=function(g,h,j){if(j.$origin){j=j.$origin;}var i=function(){if(j.$protected&&this.$caller==null){throw new Error('The method "'+h+'" cannot be called.');
|
}).hide();
|
||||||
}var l=this.caller,m=this.$caller;this.caller=m;this.$caller=i;var k=j.apply(this,arguments);this.$caller=m;this.caller=l;return k;}.extend({$owner:g,$origin:j,$name:h});
|
}
|
||||||
return i;};var f=function(h,i,g){if(a.Mutators.hasOwnProperty(h)){i=a.Mutators[h].call(this,i);if(i==null){return this;}}if(typeOf(i)=="function"){if(i.$hidden){return this;
|
} if (t == null) { return null; }t.extend(this); t.$constructor = a; t.prototype.$constructor = t; return t;
|
||||||
}this.prototype[h]=(g)?i:b(this,h,i);}else{Object.merge(this.prototype,h,i);}return this;};var d=function(g){g.$prototyping=true;var h=new g;delete g.$prototyping;
|
}; const e = Object.prototype.toString; a.isEnumerable = function (i) {
|
||||||
return h;};a.implement("implement",f.overloadSetter());a.Mutators={Extends:function(g){this.parent=g;this.prototype=d(g);},Implements:function(g){Array.from(g).each(function(j){var h=new j;for(var i in h){f.call(this,i,h[i],true);}},this);}};})();
|
return (i != null && typeof i.length === 'number' && e.call(i) != '[object Function]');
|
||||||
|
}; const q = {}; const r = function (i) { const s = o(i.prototype); return q[s] || (q[s] = []); }; var b = function (t, x) {
|
||||||
|
if (x && x.$hidden) { return; } const s = r(this); for (let u = 0; u < s.length;
|
||||||
|
u++) { const w = s[u]; if (o(w) == 'type') { b.call(w, t, x); } else { w.call(this, t, x); } } const v = this.prototype[t]; if (v == null || !v.$protected) { this.prototype[t] = x; } if (this[t] == null && o(x) == 'function') {
|
||||||
|
m.call(this, t, function (i) {
|
||||||
|
return x.apply(i, n.call(arguments, 1));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}; var m = function (i, t) { if (t && t.$hidden) { return; } const s = this[i]; if (s == null || !s.$protected) { this[i] = t; } }; a.implement({
|
||||||
|
implement: b.overloadSetter(),
|
||||||
|
extend: m.overloadSetter(),
|
||||||
|
alias: function (i, s) {
|
||||||
|
b.call(this, i, this.prototype[s]);
|
||||||
|
}.overloadSetter(),
|
||||||
|
mirror(i) { r(this).push(i); return this; },
|
||||||
|
}); new a('Type', a); var d = function (s, x, v) {
|
||||||
|
const u = (x != Object); const B = x.prototype; if (u) {
|
||||||
|
x = new a(s, x);
|
||||||
|
} for (let y = 0, w = v.length; y < w; y++) { const C = v[y]; const A = x[C]; const z = B[C]; if (A) { A.protect(); } if (u && z) { x.implement(C, z.protect()); } } if (u) {
|
||||||
|
const t = B.propertyIsEnumerable(v[0]);
|
||||||
|
x.forEachMethod = function (G) { if (!t) { for (let F = 0, D = v.length; F < D; F++) { G.call(B, B[v[F]], v[F]); } } for (const E in B) { G.call(B, B[E], E); } };
|
||||||
|
} return d;
|
||||||
|
}; d('String', String, ['charAt', 'charCodeAt', 'concat', 'indexOf', 'lastIndexOf', 'match', 'quote', 'replace', 'search', 'slice', 'split', 'substr', 'substring', 'trim', 'toLowerCase', 'toUpperCase'])('Array', Array, ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat', 'join', 'slice', 'indexOf', 'lastIndexOf', 'filter', 'forEach', 'every', 'map', 'some', 'reduce', 'reduceRight'])('Number', Number, ['toExponential', 'toFixed', 'toLocaleString', 'toPrecision'])('Function', f, ['apply', 'call', 'bind'])('RegExp', RegExp, ['exec', 'test'])('Object', Object, ['create', 'defineProperty', 'defineProperties', 'keys', 'getPrototypeOf', 'getOwnPropertyDescriptor', 'getOwnPropertyNames', 'preventExtensions', 'isExtensible', 'seal', 'isSealed', 'freeze', 'isFrozen'])('Date', Date, ['now']);
|
||||||
|
Object.extend = m.overloadSetter(); Date.extend('now', () => +(new Date())); new a('Boolean', Boolean); Number.prototype.$family = function () {
|
||||||
|
return isFinite(this) ? 'number' : 'null';
|
||||||
|
}.hide(); Number.extend('random', (s, i) => Math.floor(Math.random() * (i - s + 1) + s)); const g = Object.prototype.hasOwnProperty; Object.extend('forEach', (i, t, u) => {
|
||||||
|
for (const s in i) {
|
||||||
|
if (g.call(i, s)) {
|
||||||
|
t.call(u, i[s], s, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}); Object.each = Object.forEach; Array.implement({
|
||||||
|
forEach(u, v) { for (let t = 0, s = this.length; t < s; t++) { if (t in this) { u.call(v, this[t], t, this); } } },
|
||||||
|
each(i, s) {
|
||||||
|
Array.forEach(this, i, s);
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
}); const l = function (i) { switch (o(i)) { case 'array': return i.clone(); case 'object': return Object.clone(i); default: return i; } }; Array.implement('clone', function () {
|
||||||
|
let s = this.length; const t = new Array(s);
|
||||||
|
while (s--) { t[s] = l(this[s]); } return t;
|
||||||
|
}); const h = function (s, i, t) {
|
||||||
|
switch (o(t)) {
|
||||||
|
case 'object': if (o(s[i]) == 'object') { Object.merge(s[i], t); } else {
|
||||||
|
s[i] = Object.clone(t);
|
||||||
|
} break; case 'array': s[i] = t.clone(); break; default: s[i] = t;
|
||||||
|
} return s;
|
||||||
|
}; Object.extend({
|
||||||
|
merge(z, u, t) {
|
||||||
|
if (o(u) == 'string') { return h(z, u, t); } for (let y = 1, s = arguments.length;
|
||||||
|
y < s; y++) { const w = arguments[y]; for (const x in w) { h(z, x, w[x]); } } return z;
|
||||||
|
},
|
||||||
|
clone(i) { const t = {}; for (const s in i) { t[s] = l(i[s]); } return t; },
|
||||||
|
append(w) {
|
||||||
|
for (let v = 1, t = arguments.length;
|
||||||
|
v < t; v++) { const s = arguments[v] || {}; for (const u in s) { w[u] = s[u]; } } return w;
|
||||||
|
},
|
||||||
|
}); ['Object', 'WhiteSpace', 'TextNode', 'Collection', 'Arguments'].each((i) => {
|
||||||
|
new a(i);
|
||||||
|
}); let c = Date.now(); String.extend('uniqueID', () => (c++).toString(36));
|
||||||
|
}()); Array.implement({
|
||||||
|
every(c, d) {
|
||||||
|
for (let b = 0, a = this.length >>> 0;
|
||||||
|
b < a; b++) { if ((b in this) && !c.call(d, this[b], b, this)) { return false; } } return true;
|
||||||
|
},
|
||||||
|
filter(d, f) {
|
||||||
|
const c = []; for (var e, b = 0, a = this.length >>> 0; b < a; b++) {
|
||||||
|
if (b in this) {
|
||||||
|
e = this[b];
|
||||||
|
if (d.call(f, e, b, this)) { c.push(e); }
|
||||||
|
}
|
||||||
|
} return c;
|
||||||
|
},
|
||||||
|
indexOf(c, d) {
|
||||||
|
const b = this.length >>> 0; for (let a = (d < 0) ? Math.max(0, b + d) : d || 0; a < b; a++) {
|
||||||
|
if (this[a] === c) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
} return -1;
|
||||||
|
},
|
||||||
|
map(c, e) { const d = this.length >>> 0; const b = Array(d); for (let a = 0; a < d; a++) { if (a in this) { b[a] = c.call(e, this[a], a, this); } } return b; },
|
||||||
|
some(c, d) {
|
||||||
|
for (let b = 0, a = this.length >>> 0;
|
||||||
|
b < a; b++) { if ((b in this) && c.call(d, this[b], b, this)) { return true; } } return false;
|
||||||
|
},
|
||||||
|
clean() { return this.filter((a) => a != null); },
|
||||||
|
invoke(a) {
|
||||||
|
const b = Array.slice(arguments, 1);
|
||||||
|
return this.map((c) => c[a].apply(c, b));
|
||||||
|
},
|
||||||
|
associate(c) {
|
||||||
|
const d = {}; const b = Math.min(this.length, c.length); for (let a = 0; a < b; a++) {
|
||||||
|
d[c[a]] = this[a];
|
||||||
|
} return d;
|
||||||
|
},
|
||||||
|
link(c) { const a = {}; for (let e = 0, b = this.length; e < b; e++) { for (const d in c) { if (c[d](this[e])) { a[d] = this[e]; delete c[d]; break; } } } return a; },
|
||||||
|
contains(a, b) {
|
||||||
|
return this.indexOf(a, b) != -1;
|
||||||
|
},
|
||||||
|
append(a) { this.push.apply(this, a); return this; },
|
||||||
|
getLast() { return (this.length) ? this[this.length - 1] : null; },
|
||||||
|
getRandom() {
|
||||||
|
return (this.length) ? this[Number.random(0, this.length - 1)] : null;
|
||||||
|
},
|
||||||
|
include(a) { if (!this.contains(a)) { this.push(a); } return this; },
|
||||||
|
combine(c) {
|
||||||
|
for (let b = 0, a = c.length; b < a; b++) { this.include(c[b]); } return this;
|
||||||
|
},
|
||||||
|
erase(b) { for (let a = this.length; a--;) { if (this[a] === b) { this.splice(a, 1); } } return this; },
|
||||||
|
empty() { this.length = 0; return this; },
|
||||||
|
flatten() {
|
||||||
|
let d = [];
|
||||||
|
for (let b = 0, a = this.length; b < a; b++) {
|
||||||
|
const c = typeOf(this[b]); if (c == 'null') { continue; }d = d.concat((c == 'array' || c == 'collection' || c == 'arguments' || instanceOf(this[b], Array)) ? Array.flatten(this[b]) : this[b]);
|
||||||
|
} return d;
|
||||||
|
},
|
||||||
|
pick() { for (let b = 0, a = this.length; b < a; b++) { if (this[b] != null) { return this[b]; } } return null; },
|
||||||
|
rgbToHex(d) {
|
||||||
|
if (this.length < 3) { return null; } if (this.length == 4 && this[3] == 0 && !d) {
|
||||||
|
return 'transparent';
|
||||||
|
} const b = []; for (let a = 0; a < 3; a++) { const c = (this[a] - 0).toString(16); b.push((c.length == 1) ? `0${c}` : c); } return (d) ? b : `#${b.join('')}`;
|
||||||
|
},
|
||||||
|
}); String.implement({
|
||||||
|
test(a, b) {
|
||||||
|
return ((typeOf(a) == 'regexp') ? a : new RegExp(`${a}`, b)).test(this);
|
||||||
|
},
|
||||||
|
contains(a, b) { return (b) ? (b + this + b).indexOf(b + a + b) > -1 : String(this).indexOf(a) > -1; },
|
||||||
|
trim() {
|
||||||
|
return String(this).replace(/^\s+|\s+$/g, '');
|
||||||
|
},
|
||||||
|
clean() { return String(this).replace(/\s+/g, ' ').trim(); },
|
||||||
|
camelCase() {
|
||||||
|
return String(this).replace(/-\D/g, (a) => a.charAt(1).toUpperCase());
|
||||||
|
},
|
||||||
|
hyphenate() { return String(this).replace(/[A-Z]/g, (a) => (`-${a.charAt(0).toLowerCase()}`)); },
|
||||||
|
capitalize() {
|
||||||
|
return String(this).replace(/\b[a-z]/g, (a) => a.toUpperCase());
|
||||||
|
},
|
||||||
|
escapeRegExp() { return String(this).replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1'); },
|
||||||
|
rgbToHex(b) {
|
||||||
|
const a = String(this).match(/\d{1,3}/g);
|
||||||
|
return (a) ? a.rgbToHex(b) : null;
|
||||||
|
},
|
||||||
|
substitute(a, b) {
|
||||||
|
return String(this).replace(b || (/\\?\{([^{}]+)\}/g), (d, c) => {
|
||||||
|
if (d.charAt(0) == '\\') {
|
||||||
|
return d.slice(1);
|
||||||
|
} return (a[c] != null) ? a[c] : '';
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
Function.implement({ bind(e) { const a = this; const b = arguments.length > 1 ? Array.slice(arguments, 1) : null; const d = function () {}; var c = function () { let g = e; const h = arguments.length; if (this instanceof c) { d.prototype = a.prototype; g = new d(); } const f = (!b && !h) ? a.call(g) : a.apply(g, b && h ? b.concat(Array.slice(arguments)) : b || arguments); return g == e ? f : g; }; return c; }, pass(b, c) { const a = this; if (b != null) { b = Array.from(b); } return function () { return a.apply(c, b || arguments); }; }, delay(b, c, a) { return setTimeout(this.pass((a == null ? [] : a), c), b); } });
|
||||||
|
Number.alias('each', 'times'); (function (b) {
|
||||||
|
const a = {}; b.each((c) => {
|
||||||
|
if (!Number[c]) {
|
||||||
|
a[c] = function () {
|
||||||
|
return Math[c].apply(null, [this].concat(Array.from(arguments)));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}); Number.implement(a);
|
||||||
|
}(['abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'log', 'max', 'min', 'pow', 'sin', 'sqrt', 'tan'])); (function () {
|
||||||
|
var a = this.Class = new Type('Class', function (h) {
|
||||||
|
if (instanceOf(h, Function)) {
|
||||||
|
h = { initialize: h };
|
||||||
|
} var g = function () {
|
||||||
|
e(this); if (g.$prototyping) { return this; } this.$caller = null; const i = (this.initialize) ? this.initialize.apply(this, arguments) : this; this.$caller = this.caller = null;
|
||||||
|
return i;
|
||||||
|
}.extend(this).implement(h); g.$constructor = a; g.prototype.$constructor = g; g.prototype.parent = c; return g;
|
||||||
|
}); var c = function () {
|
||||||
|
if (!this.$caller) {
|
||||||
|
throw new Error('The method "parent" cannot be called.');
|
||||||
|
} const g = this.$caller.$name; const h = this.$caller.$owner.parent; const i = (h) ? h.prototype[g] : null; if (!i) { throw new Error(`The method "${g}" has no parent.`); } return i.apply(this, arguments);
|
||||||
|
}; var e = function (g) {
|
||||||
|
for (const h in g) {
|
||||||
|
const j = g[h]; switch (typeOf(j)) {
|
||||||
|
case 'object': var i = function () {}; i.prototype = j; g[h] = e(new i()); break; case 'array': g[h] = j.clone();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} return g;
|
||||||
|
}; const b = function (g, h, j) {
|
||||||
|
if (j.$origin) { j = j.$origin; } var i = function () {
|
||||||
|
if (j.$protected && this.$caller == null) {
|
||||||
|
throw new Error(`The method "${h}" cannot be called.`);
|
||||||
|
} const l = this.caller; const m = this.$caller; this.caller = m; this.$caller = i; const k = j.apply(this, arguments); this.$caller = m; this.caller = l; return k;
|
||||||
|
}.extend({ $owner: g, $origin: j, $name: h });
|
||||||
|
return i;
|
||||||
|
}; const f = function (h, i, g) {
|
||||||
|
if (a.Mutators.hasOwnProperty(h)) { i = a.Mutators[h].call(this, i); if (i == null) { return this; } } if (typeOf(i) == 'function') {
|
||||||
|
if (i.$hidden) {
|
||||||
|
return this;
|
||||||
|
} this.prototype[h] = (g) ? i : b(this, h, i);
|
||||||
|
} else { Object.merge(this.prototype, h, i); } return this;
|
||||||
|
}; const d = function (g) {
|
||||||
|
g.$prototyping = true; const h = new g(); delete g.$prototyping;
|
||||||
|
return h;
|
||||||
|
}; a.implement('implement', f.overloadSetter()); a.Mutators = { Extends(g) { this.parent = g; this.prototype = d(g); }, Implements(g) { Array.from(g).each(function (j) { const h = new j(); for (const i in h) { f.call(this, i, h[i], true); } }, this); } };
|
||||||
|
}());
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -17,75 +17,75 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const FeatureModel = new Class(/** @lends FeatureModel */{
|
const FeatureModel = new Class(/** @lends FeatureModel */{
|
||||||
Static:{
|
Static: {
|
||||||
_nextUUID:function () {
|
_nextUUID() {
|
||||||
if (!$defined(FeatureModel._uuid)) {
|
if (!$defined(FeatureModel._uuid)) {
|
||||||
FeatureModel._uuid = 0;
|
FeatureModel._uuid = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FeatureModel._uuid = FeatureModel._uuid + 1;
|
FeatureModel._uuid += 1;
|
||||||
return FeatureModel._uuid;
|
return FeatureModel._uuid;
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructs
|
* @constructs
|
||||||
* @param type
|
* @param type
|
||||||
* @throws will throw an exception if type is null or undefined
|
* @throws will throw an exception if type is null or undefined
|
||||||
* assigns a unique id and the given type to the new model
|
* assigns a unique id and the given type to the new model
|
||||||
*/
|
*/
|
||||||
initialize:function (type) {
|
initialize(type) {
|
||||||
$assert(type, 'type can not be null');
|
$assert(type, 'type can not be null');
|
||||||
this._id = FeatureModel._nextUUID();
|
this._id = FeatureModel._nextUUID();
|
||||||
|
|
||||||
this._type = type;
|
this._type = type;
|
||||||
this._attributes = {};
|
this._attributes = {};
|
||||||
|
|
||||||
// Create type method ...
|
// Create type method ...
|
||||||
this['is' + $.camelCase(type) + 'Model'] = function () {
|
this[`is${$.camelCase(type)}Model`] = function () {
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getAttributes:function () {
|
getAttributes() {
|
||||||
return Object.clone(this._attributes);
|
return Object.clone(this._attributes);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setAttributes:function (attributes) {
|
setAttributes(attributes) {
|
||||||
for (key in attributes) {
|
for (key in attributes) {
|
||||||
this["set" + key.capitalize()](attributes[key]);
|
this[`set${key.capitalize()}`](attributes[key]);
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/** */
|
|
||||||
setAttribute:function (key, value) {
|
|
||||||
$assert(key, 'key id can not be null');
|
|
||||||
this._attributes[key] = value;
|
|
||||||
},
|
|
||||||
|
|
||||||
/** */
|
|
||||||
getAttribute:function (key) {
|
|
||||||
$assert(key, 'key id can not be null');
|
|
||||||
|
|
||||||
return this._attributes[key];
|
|
||||||
},
|
|
||||||
|
|
||||||
/** */
|
|
||||||
getId:function () {
|
|
||||||
return this._id;
|
|
||||||
},
|
|
||||||
|
|
||||||
/** */
|
|
||||||
setId:function (id) {
|
|
||||||
this._id = id;
|
|
||||||
},
|
|
||||||
|
|
||||||
/** */
|
|
||||||
getType:function () {
|
|
||||||
return this._type;
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/** */
|
||||||
|
setAttribute(key, value) {
|
||||||
|
$assert(key, 'key id can not be null');
|
||||||
|
this._attributes[key] = value;
|
||||||
|
},
|
||||||
|
|
||||||
|
/** */
|
||||||
|
getAttribute(key) {
|
||||||
|
$assert(key, 'key id can not be null');
|
||||||
|
|
||||||
|
return this._attributes[key];
|
||||||
|
},
|
||||||
|
|
||||||
|
/** */
|
||||||
|
getId() {
|
||||||
|
return this._id;
|
||||||
|
},
|
||||||
|
|
||||||
|
/** */
|
||||||
|
setId(id) {
|
||||||
|
this._id = id;
|
||||||
|
},
|
||||||
|
|
||||||
|
/** */
|
||||||
|
getType() {
|
||||||
|
return this._type;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default FeatureModel;
|
export default FeatureModel;
|
||||||
|
@ -17,165 +17,165 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const IMindmap = new Class(/** @lends IMindmap */{
|
const IMindmap = new Class(/** @lends IMindmap */{
|
||||||
/**
|
/**
|
||||||
* @constructs
|
* @constructs
|
||||||
* @abstract
|
* @abstract
|
||||||
*/
|
*/
|
||||||
initialize : function() {
|
initialize() {
|
||||||
throw "Unsupported operation";
|
throw 'Unsupported operation';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getCentralTopic : function() {
|
getCentralTopic() {
|
||||||
return this.getBranches()[0];
|
return this.getBranches()[0];
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
getDescription : function() {
|
getDescription() {
|
||||||
throw "Unsupported operation";
|
throw 'Unsupported operation';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
setDescription : function(value) {
|
setDescription(value) {
|
||||||
throw "Unsupported operation";
|
throw 'Unsupported operation';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
getId : function() {
|
getId() {
|
||||||
throw "Unsupported operation";
|
throw 'Unsupported operation';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
setId : function(id) {
|
setId(id) {
|
||||||
throw "Unsupported operation";
|
throw 'Unsupported operation';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
getVersion : function() {
|
getVersion() {
|
||||||
throw "Unsupported operation";
|
throw 'Unsupported operation';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
setVersion : function(version) {
|
setVersion(version) {
|
||||||
throw "Unsupported operation";
|
throw 'Unsupported operation';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
addBranch : function(nodeModel) {
|
addBranch(nodeModel) {
|
||||||
throw "Unsupported operation";
|
throw 'Unsupported operation';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
getBranches : function() {
|
getBranches() {
|
||||||
throw "Unsupported operation";
|
throw 'Unsupported operation';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
removeBranch : function(node) {
|
removeBranch(node) {
|
||||||
throw "Unsupported operation";
|
throw 'Unsupported operation';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
getRelationships : function() {
|
getRelationships() {
|
||||||
throw "Unsupported operation";
|
throw 'Unsupported operation';
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param parent
|
* @param parent
|
||||||
* @param child
|
* @param child
|
||||||
* @throws will throw an error if child already has a connection to a parent node
|
* @throws will throw an error if child already has a connection to a parent node
|
||||||
*/
|
*/
|
||||||
connect : function(parent, child) {
|
connect(parent, child) {
|
||||||
// Child already has a parent ?
|
// Child already has a parent ?
|
||||||
$assert(!child.getParent(), 'Child model seems to be already connected');
|
$assert(!child.getParent(), 'Child model seems to be already connected');
|
||||||
|
|
||||||
// Connect node...
|
// Connect node...
|
||||||
parent.append(child);
|
parent.append(child);
|
||||||
|
|
||||||
// Remove from the branch ...
|
// Remove from the branch ...
|
||||||
this.removeBranch(child);
|
this.removeBranch(child);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param child
|
* @param child
|
||||||
* @throws will throw an error if child is null or undefined
|
* @throws will throw an error if child is null or undefined
|
||||||
* @throws will throw an error if child's parent cannot be found
|
* @throws will throw an error if child's parent cannot be found
|
||||||
*/
|
*/
|
||||||
disconnect : function(child) {
|
disconnect(child) {
|
||||||
var parent = child.getParent();
|
const parent = child.getParent();
|
||||||
$assert(child, 'Child can not be null.');
|
$assert(child, 'Child can not be null.');
|
||||||
$assert(parent, 'Child model seems to be already connected');
|
$assert(parent, 'Child model seems to be already connected');
|
||||||
|
|
||||||
parent.removeChild(child);
|
parent.removeChild(child);
|
||||||
this.addBranch(child);
|
this.addBranch(child);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
hasAlreadyAdded : function(node) {
|
hasAlreadyAdded(node) {
|
||||||
throw "Unsupported operation";
|
throw 'Unsupported operation';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
createNode : function(type, id) {
|
createNode(type, id) {
|
||||||
throw "Unsupported operation";
|
throw 'Unsupported operation';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
createRelationship : function(fromNode, toNode) {
|
createRelationship(fromNode, toNode) {
|
||||||
throw "Unsupported operation";
|
throw 'Unsupported operation';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
addRelationship : function(rel) {
|
addRelationship(rel) {
|
||||||
throw "Unsupported operation";
|
throw 'Unsupported operation';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
deleteRelationship : function(relationship) {
|
deleteRelationship(relationship) {
|
||||||
throw "Unsupported operation";
|
throw 'Unsupported operation';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
inspect : function() {
|
inspect() {
|
||||||
var result = '';
|
let result = '';
|
||||||
result = '{ ';
|
result = '{ ';
|
||||||
|
|
||||||
var branches = this.getBranches();
|
const branches = this.getBranches();
|
||||||
result = result + "version:" + this.getVersion();
|
result = `${result}version:${this.getVersion()}`;
|
||||||
result = result + " , [";
|
result = `${result} , [`;
|
||||||
|
|
||||||
for (var i = 0; i < branches.length; i++) {
|
for (let i = 0; i < branches.length; i++) {
|
||||||
var node = branches[i];
|
const node = branches[i];
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
result = result + ',\n ';
|
result = `${result},\n `;
|
||||||
}
|
}
|
||||||
result = result + "(" + i + ") =>" + node.inspect();
|
result = `${result}(${i}) =>${node.inspect()}`;
|
||||||
}
|
}
|
||||||
result = result + "]";
|
result = `${result}]`;
|
||||||
|
|
||||||
result = result + ' } ';
|
result = `${result} } `;
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param target
|
* @param target
|
||||||
*/
|
*/
|
||||||
copyTo : function(target) {
|
copyTo(target) {
|
||||||
var source = this;
|
const source = this;
|
||||||
var version = source.getVersion();
|
const version = source.getVersion();
|
||||||
target.setVersion(version);
|
target.setVersion(version);
|
||||||
|
|
||||||
var desc = this.getDescription();
|
const desc = this.getDescription();
|
||||||
target.setDescription(desc);
|
target.setDescription(desc);
|
||||||
|
|
||||||
// Then the rest of the branches ...
|
// Then the rest of the branches ...
|
||||||
var sbranchs = source.getBranches();
|
const sbranchs = source.getBranches();
|
||||||
_.each(sbranchs, function(snode) {
|
_.each(sbranchs, (snode) => {
|
||||||
var tnode = target.createNode(snode.getType(), snode.getId());
|
const tnode = target.createNode(snode.getType(), snode.getId());
|
||||||
snode.copyTo(tnode);
|
snode.copyTo(tnode);
|
||||||
target.addBranch(tnode);
|
target.addBranch(tnode);
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default IMindmap
|
export default IMindmap;
|
||||||
|
@ -17,375 +17,374 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const INodeModel = new Class(
|
const INodeModel = new Class(
|
||||||
/** @lends INodeModel */ {
|
/** @lends INodeModel */ {
|
||||||
/**
|
/**
|
||||||
* @constructs
|
* @constructs
|
||||||
* @param mindmap
|
* @param mindmap
|
||||||
*/
|
*/
|
||||||
initialize: function (mindmap) {
|
initialize(mindmap) {
|
||||||
$assert(mindmap && mindmap.getBranches, 'mindmap can not be null');
|
$assert(mindmap && mindmap.getBranches, 'mindmap can not be null');
|
||||||
this._mindmap = mindmap;
|
this._mindmap = mindmap;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getId: function () {
|
getId() {
|
||||||
return this.getProperty('id');
|
return this.getProperty('id');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setId: function (id) {
|
setId(id) {
|
||||||
if ($defined(id) && id > INodeModel._uuid) {
|
if ($defined(id) && id > INodeModel._uuid) {
|
||||||
INodeModel._uuid = id;
|
INodeModel._uuid = id;
|
||||||
}
|
}
|
||||||
if (!$defined(id)) {
|
if (!$defined(id)) {
|
||||||
id = INodeModel._nextUUID();
|
id = INodeModel._nextUUID();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.putProperty('id', id);
|
this.putProperty('id', id);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getType: function () {
|
getType() {
|
||||||
return this.getProperty('type');
|
return this.getProperty('type');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setType: function (type) {
|
setType(type) {
|
||||||
this.putProperty('type', type);
|
this.putProperty('type', type);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setText: function (text) {
|
setText(text) {
|
||||||
this.putProperty('text', text);
|
this.putProperty('text', text);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getText: function () {
|
getText() {
|
||||||
return this.getProperty('text');
|
return this.getProperty('text');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setPosition: function (x, y) {
|
setPosition(x, y) {
|
||||||
$assert(!isNaN(parseInt(x)), 'x position is not valid:' + x);
|
$assert(!isNaN(parseInt(x)), `x position is not valid:${x}`);
|
||||||
$assert(!isNaN(parseInt(y)), 'y position is not valid:' + y);
|
$assert(!isNaN(parseInt(y)), `y position is not valid:${y}`);
|
||||||
this.putProperty('position', '{x:' + parseInt(x) + ',y:' + parseInt(y) + '}');
|
this.putProperty('position', `{x:${parseInt(x)},y:${parseInt(y)}}`);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getPosition: function () {
|
getPosition() {
|
||||||
var value = this.getProperty('position');
|
const value = this.getProperty('position');
|
||||||
var result = null;
|
let result = null;
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
result = eval('(' + value + ')');
|
result = eval(`(${value})`);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setImageSize: function (width, height) {
|
setImageSize(width, height) {
|
||||||
this.putProperty('imageSize', '{width:' + width + ',height:' + height + '}');
|
this.putProperty('imageSize', `{width:${width},height:${height}}`);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getImageSize: function () {
|
getImageSize() {
|
||||||
var value = this.getProperty('imageSize');
|
const value = this.getProperty('imageSize');
|
||||||
var result = null;
|
let result = null;
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
result = eval('(' + value + ')');
|
result = eval(`(${value})`);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setImageUrl: function (url) {
|
setImageUrl(url) {
|
||||||
this.putProperty('imageUrl', url);
|
this.putProperty('imageUrl', url);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getMetadata: function () {
|
getMetadata() {
|
||||||
return this.getProperty('metadata');
|
return this.getProperty('metadata');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setMetadata: function (json) {
|
setMetadata(json) {
|
||||||
this.putProperty('metadata', json);
|
this.putProperty('metadata', json);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getImageUrl: function () {
|
getImageUrl() {
|
||||||
return this.getProperty('imageUrl');
|
return this.getProperty('imageUrl');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getMindmap: function () {
|
getMindmap() {
|
||||||
return this._mindmap;
|
return this._mindmap;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* lets the mindmap handle the disconnect node operation
|
* lets the mindmap handle the disconnect node operation
|
||||||
* @see mindplot.model.IMindmap.disconnect
|
* @see mindplot.model.IMindmap.disconnect
|
||||||
*/
|
*/
|
||||||
disconnect: function () {
|
disconnect() {
|
||||||
var mindmap = this.getMindmap();
|
const mindmap = this.getMindmap();
|
||||||
mindmap.disconnect(this);
|
mindmap.disconnect(this);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getShapeType: function () {
|
getShapeType() {
|
||||||
return this.getProperty('shapeType');
|
return this.getProperty('shapeType');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setShapeType: function (type) {
|
setShapeType(type) {
|
||||||
this.putProperty('shapeType', type);
|
this.putProperty('shapeType', type);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setOrder: function (value) {
|
setOrder(value) {
|
||||||
$assert(
|
$assert(
|
||||||
(typeof value === 'number' && isFinite(value)) || value == null,
|
(typeof value === 'number' && isFinite(value)) || value == null,
|
||||||
'Order must be null or a number'
|
'Order must be null or a number',
|
||||||
);
|
);
|
||||||
this.putProperty('order', value);
|
this.putProperty('order', value);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getOrder: function () {
|
getOrder() {
|
||||||
return this.getProperty('order');
|
return this.getProperty('order');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setFontFamily: function (fontFamily) {
|
setFontFamily(fontFamily) {
|
||||||
this.putProperty('fontFamily', fontFamily);
|
this.putProperty('fontFamily', fontFamily);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getFontFamily: function () {
|
getFontFamily() {
|
||||||
return this.getProperty('fontFamily');
|
return this.getProperty('fontFamily');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setFontStyle: function (fontStyle) {
|
setFontStyle(fontStyle) {
|
||||||
this.putProperty('fontStyle', fontStyle);
|
this.putProperty('fontStyle', fontStyle);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getFontStyle: function () {
|
getFontStyle() {
|
||||||
return this.getProperty('fontStyle');
|
return this.getProperty('fontStyle');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setFontWeight: function (weight) {
|
setFontWeight(weight) {
|
||||||
this.putProperty('fontWeight', weight);
|
this.putProperty('fontWeight', weight);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getFontWeight: function () {
|
getFontWeight() {
|
||||||
return this.getProperty('fontWeight');
|
return this.getProperty('fontWeight');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setFontColor: function (color) {
|
setFontColor(color) {
|
||||||
this.putProperty('fontColor', color);
|
this.putProperty('fontColor', color);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getFontColor: function () {
|
getFontColor() {
|
||||||
return this.getProperty('fontColor');
|
return this.getProperty('fontColor');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setFontSize: function (size) {
|
setFontSize(size) {
|
||||||
this.putProperty('fontSize', size);
|
this.putProperty('fontSize', size);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getFontSize: function () {
|
getFontSize() {
|
||||||
return this.getProperty('fontSize');
|
return this.getProperty('fontSize');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getBorderColor: function () {
|
getBorderColor() {
|
||||||
return this.getProperty('borderColor');
|
return this.getProperty('borderColor');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setBorderColor: function (color) {
|
setBorderColor(color) {
|
||||||
this.putProperty('borderColor', color);
|
this.putProperty('borderColor', color);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getBackgroundColor: function () {
|
getBackgroundColor() {
|
||||||
return this.getProperty('backgroundColor');
|
return this.getProperty('backgroundColor');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setBackgroundColor: function (color) {
|
setBackgroundColor(color) {
|
||||||
this.putProperty('backgroundColor', color);
|
this.putProperty('backgroundColor', color);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
areChildrenShrunken: function () {
|
areChildrenShrunken() {
|
||||||
var result = this.getProperty('shrunken');
|
const result = this.getProperty('shrunken');
|
||||||
return $defined(result) ? result : false;
|
return $defined(result) ? result : false;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {Boolean} true if the children nodes are hidden by the shrink option
|
* @return {Boolean} true if the children nodes are hidden by the shrink option
|
||||||
*/
|
*/
|
||||||
setChildrenShrunken: function (value) {
|
setChildrenShrunken(value) {
|
||||||
this.putProperty('shrunken', value);
|
this.putProperty('shrunken', value);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {Boolean} true
|
* @return {Boolean} true
|
||||||
*/
|
*/
|
||||||
isNodeModel: function () {
|
isNodeModel() {
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {Boolean} true if the node model has a parent assigned to it
|
* @return {Boolean} true if the node model has a parent assigned to it
|
||||||
*/
|
*/
|
||||||
isConnected: function () {
|
isConnected() {
|
||||||
return this.getParent() != null;
|
return this.getParent() != null;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
append: function (node) {
|
append(node) {
|
||||||
throw 'Unsupported operation';
|
throw 'Unsupported operation';
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* lets the mindmap handle the connect node operation
|
* lets the mindmap handle the connect node operation
|
||||||
* @throws will throw an error if parent is null or undefined
|
* @throws will throw an error if parent is null or undefined
|
||||||
* @see mindplot.model.IMindmap.connect
|
* @see mindplot.model.IMindmap.connect
|
||||||
*/
|
*/
|
||||||
connectTo: function (parent) {
|
connectTo(parent) {
|
||||||
$assert(parent, 'parent can not be null');
|
$assert(parent, 'parent can not be null');
|
||||||
var mindmap = this.getMindmap();
|
const mindmap = this.getMindmap();
|
||||||
mindmap.connect(parent, this);
|
mindmap.connect(parent, this);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param target
|
* @param target
|
||||||
* @return target
|
* @return target
|
||||||
*/
|
*/
|
||||||
copyTo: function (target) {
|
copyTo(target) {
|
||||||
var source = this;
|
const source = this;
|
||||||
// Copy properties ...
|
// Copy properties ...
|
||||||
var keys = source.getPropertiesKeys();
|
const keys = source.getPropertiesKeys();
|
||||||
_.each(keys, function (key) {
|
_.each(keys, (key) => {
|
||||||
var value = source.getProperty(key);
|
const value = source.getProperty(key);
|
||||||
target.putProperty(key, value);
|
target.putProperty(key, value);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Copy children ...
|
// Copy children ...
|
||||||
var children = this.getChildren();
|
const children = this.getChildren();
|
||||||
var tmindmap = target.getMindmap();
|
const tmindmap = target.getMindmap();
|
||||||
|
|
||||||
_.each(function (children, snode) {
|
_.each((children, snode) => {
|
||||||
var tnode = tmindmap.createNode(snode.getType(), snode.getId());
|
const tnode = tmindmap.createNode(snode.getType(), snode.getId());
|
||||||
snode.copyTo(tnode);
|
snode.copyTo(tnode);
|
||||||
target.append(tnode);
|
target.append(tnode);
|
||||||
});
|
});
|
||||||
|
|
||||||
return target;
|
return target;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* lets parent handle the delete node operation, or, if none defined, calls the mindmap to
|
* lets parent handle the delete node operation, or, if none defined, calls the mindmap to
|
||||||
* remove the respective branch
|
* remove the respective branch
|
||||||
*/
|
*/
|
||||||
deleteNode: function () {
|
deleteNode() {
|
||||||
var mindmap = this.getMindmap();
|
const mindmap = this.getMindmap();
|
||||||
|
|
||||||
// console.log("Before:" + mindmap.inspect());
|
// console.log("Before:" + mindmap.inspect());
|
||||||
var parent = this.getParent();
|
const parent = this.getParent();
|
||||||
if ($defined(parent)) {
|
if ($defined(parent)) {
|
||||||
parent.removeChild(this);
|
parent.removeChild(this);
|
||||||
} else {
|
} else {
|
||||||
// If it has not parent, it must be an isolate topic ...
|
// If it has not parent, it must be an isolate topic ...
|
||||||
mindmap.removeBranch(this);
|
mindmap.removeBranch(this);
|
||||||
}
|
}
|
||||||
// It's an isolated node. It must be a hole branch ...
|
// It's an isolated node. It must be a hole branch ...
|
||||||
// console.log("After:" + mindmap.inspect());
|
// console.log("After:" + mindmap.inspect());
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
getPropertiesKeys: function () {
|
getPropertiesKeys() {
|
||||||
throw 'Unsupported operation';
|
throw 'Unsupported operation';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
putProperty: function (key, value) {
|
putProperty(key, value) {
|
||||||
throw 'Unsupported operation';
|
throw 'Unsupported operation';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
setParent: function (parent) {
|
setParent(parent) {
|
||||||
throw 'Unsupported operation';
|
throw 'Unsupported operation';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
getChildren: function () {
|
getChildren() {
|
||||||
throw 'Unsupported operation';
|
throw 'Unsupported operation';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
getParent: function () {
|
getParent() {
|
||||||
throw 'Unsupported operation';
|
throw 'Unsupported operation';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
clone: function () {
|
clone() {
|
||||||
throw 'Unsupported operation';
|
throw 'Unsupported operation';
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
inspect: function () {
|
inspect() {
|
||||||
var result =
|
let result = `{ type: ${
|
||||||
'{ type: ' +
|
this.getType()
|
||||||
this.getType() +
|
} , id: ${
|
||||||
' , id: ' +
|
this.getId()
|
||||||
this.getId() +
|
} , text: ${
|
||||||
' , text: ' +
|
this.getText()}`;
|
||||||
this.getText();
|
|
||||||
|
|
||||||
var children = this.getChildren();
|
const children = this.getChildren();
|
||||||
if (children.length > 0) {
|
if (children.length > 0) {
|
||||||
result = result + ', children: {(size:' + children.length;
|
result = `${result}, children: {(size:${children.length}`;
|
||||||
_.each(children, function (node) {
|
_.each(children, (node) => {
|
||||||
result = result + '=> (';
|
result = `${result}=> (`;
|
||||||
var keys = node.getPropertiesKeys();
|
const keys = node.getPropertiesKeys();
|
||||||
_.each(keys, function (key) {
|
_.each(keys, (key) => {
|
||||||
var value = node.getProperty(key);
|
const value = node.getProperty(key);
|
||||||
result = result + key + ':' + value + ',';
|
result = `${result + key}:${value},`;
|
||||||
});
|
});
|
||||||
result = result + '}';
|
result = `${result}}`;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
result = result + ' }';
|
result = `${result} }`;
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
removeChild: function (child) {
|
removeChild(child) {
|
||||||
throw 'Unsupported operation';
|
throw 'Unsupported operation';
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {String}
|
* @enum {String}
|
||||||
*/
|
*/
|
||||||
const TopicShape = {
|
const TopicShape = {
|
||||||
RECTANGLE: 'rectagle',
|
RECTANGLE: 'rectagle',
|
||||||
ROUNDED_RECT: 'rounded rectagle',
|
ROUNDED_RECT: 'rounded rectagle',
|
||||||
ELLIPSE: 'elipse',
|
ELLIPSE: 'elipse',
|
||||||
LINE: 'line',
|
LINE: 'line',
|
||||||
IMAGE: 'image',
|
IMAGE: 'image',
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -412,12 +411,12 @@ INodeModel.MAIN_TOPIC_TO_MAIN_TOPIC_DISTANCE = 220;
|
|||||||
* @todo: This method must be implemented. (unascribed)
|
* @todo: This method must be implemented. (unascribed)
|
||||||
*/
|
*/
|
||||||
INodeModel._nextUUID = function () {
|
INodeModel._nextUUID = function () {
|
||||||
if (!$defined(INodeModel._uuid)) {
|
if (!$defined(INodeModel._uuid)) {
|
||||||
INodeModel._uuid = 0;
|
INodeModel._uuid = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
INodeModel._uuid = INodeModel._uuid + 1;
|
INodeModel._uuid += 1;
|
||||||
return INodeModel._uuid;
|
return INodeModel._uuid;
|
||||||
};
|
};
|
||||||
INodeModel._uuid = 0;
|
INodeModel._uuid = 0;
|
||||||
|
|
||||||
|
@ -15,30 +15,30 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
const FeatureModel = require('./FeatureModel').default
|
const FeatureModel = require('./FeatureModel').default;
|
||||||
|
|
||||||
const IconModel = new Class(/** @lends IconModel */{
|
const IconModel = new Class(/** @lends IconModel */{
|
||||||
Extends: FeatureModel,
|
Extends: FeatureModel,
|
||||||
/**
|
/**
|
||||||
* @constructs
|
* @constructs
|
||||||
* @param attributes
|
* @param attributes
|
||||||
* @extends mindplot.model.FeatureModel
|
* @extends mindplot.model.FeatureModel
|
||||||
*/
|
*/
|
||||||
initialize:function (attributes) {
|
initialize(attributes) {
|
||||||
this.parent(IconModel.FEATURE_TYPE);
|
this.parent(IconModel.FEATURE_TYPE);
|
||||||
this.setIconType(attributes.id);
|
this.setIconType(attributes.id);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @return the icon type id */
|
/** @return the icon type id */
|
||||||
getIconType:function () {
|
getIconType() {
|
||||||
return this.getAttribute('id');
|
return this.getAttribute('id');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @param {String} iconType the icon type id*/
|
/** @param {String} iconType the icon type id */
|
||||||
setIconType:function (iconType) {
|
setIconType(iconType) {
|
||||||
$assert(iconType, 'iconType id can not be null');
|
$assert(iconType, 'iconType id can not be null');
|
||||||
this.setAttribute('id', iconType);
|
this.setAttribute('id', iconType);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,6 +46,6 @@ const IconModel = new Class(/** @lends IconModel */{
|
|||||||
* @type {String}
|
* @type {String}
|
||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
IconModel.FEATURE_TYPE = "icon";
|
IconModel.FEATURE_TYPE = 'icon';
|
||||||
|
|
||||||
export default IconModel;
|
export default IconModel;
|
||||||
|
@ -18,54 +18,53 @@
|
|||||||
const FeatureModel = require('./FeatureModel').default;
|
const FeatureModel = require('./FeatureModel').default;
|
||||||
|
|
||||||
const LinkModel = new Class(/** @lends LinkModel */{
|
const LinkModel = new Class(/** @lends LinkModel */{
|
||||||
Extends:FeatureModel,
|
Extends: FeatureModel,
|
||||||
/**
|
/**
|
||||||
* @constructs
|
* @constructs
|
||||||
* @param attributes
|
* @param attributes
|
||||||
* @extends mindplot.model.FeatureModel
|
* @extends mindplot.model.FeatureModel
|
||||||
*/
|
*/
|
||||||
initialize:function (attributes) {
|
initialize(attributes) {
|
||||||
this.parent(LinkModel.FEATURE_TYPE);
|
this.parent(LinkModel.FEATURE_TYPE);
|
||||||
this.setUrl(attributes.url);
|
this.setUrl(attributes.url);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** @return {String} the url attribute value */
|
/** @return {String} the url attribute value */
|
||||||
getUrl:function () {
|
getUrl() {
|
||||||
return this.getAttribute('url');
|
return this.getAttribute('url');
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {String} url a URL provided by the user to set the link to
|
* @param {String} url a URL provided by the user to set the link to
|
||||||
* @throws will throw an error if url is null or undefined
|
* @throws will throw an error if url is null or undefined
|
||||||
*/
|
*/
|
||||||
setUrl:function (url) {
|
setUrl(url) {
|
||||||
$assert(url, 'url can not be null');
|
$assert(url, 'url can not be null');
|
||||||
|
|
||||||
var fixedUrl = this._fixUrl(url);
|
const fixedUrl = this._fixUrl(url);
|
||||||
this.setAttribute('url', fixedUrl);
|
this.setAttribute('url', fixedUrl);
|
||||||
|
|
||||||
var type = fixedUrl.contains('mailto:') ? 'mail' : 'url';
|
const type = fixedUrl.contains('mailto:') ? 'mail' : 'url';
|
||||||
this.setAttribute('urlType', type);
|
this.setAttribute('urlType', type);
|
||||||
|
},
|
||||||
|
|
||||||
},
|
// url format is already checked in LinkEditor.checkUrl
|
||||||
|
_fixUrl(url) {
|
||||||
|
let result = url;
|
||||||
|
if (!result.contains('http://') && !result.contains('https://') && !result.contains('mailto://')) {
|
||||||
|
result = `http://${result}`;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
//url format is already checked in LinkEditor.checkUrl
|
/**
|
||||||
_fixUrl:function (url) {
|
|
||||||
var result = url;
|
|
||||||
if (!result.contains('http://') && !result.contains('https://') && !result.contains('mailto://')) {
|
|
||||||
result = "http://" + result;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {String} urlType the url type, either 'mail' or 'url'
|
* @param {String} urlType the url type, either 'mail' or 'url'
|
||||||
* @throws will throw an error if urlType is null or undefined
|
* @throws will throw an error if urlType is null or undefined
|
||||||
*/
|
*/
|
||||||
setUrlType:function (urlType) {
|
setUrlType(urlType) {
|
||||||
$assert(urlType, 'urlType can not be null');
|
$assert(urlType, 'urlType can not be null');
|
||||||
this.setAttribute('urlType', urlType);
|
this.setAttribute('urlType', urlType);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,173 +19,172 @@ const IMindmap = require('./IMindmap').default;
|
|||||||
const INodeModel = require('./INodeModel').default;
|
const INodeModel = require('./INodeModel').default;
|
||||||
const NodeModel = require('./NodeModel').default;
|
const NodeModel = require('./NodeModel').default;
|
||||||
const RelationshipModel = require('./RelationshipModel').default;
|
const RelationshipModel = require('./RelationshipModel').default;
|
||||||
const ModelCodeName = require('../persistence/ModelCodeName').default
|
const ModelCodeName = require('../persistence/ModelCodeName').default;
|
||||||
|
|
||||||
const Mindmap = new Class(/** @lends Mindmap */{
|
const Mindmap = new Class(/** @lends Mindmap */{
|
||||||
Extends:IMindmap,
|
Extends: IMindmap,
|
||||||
/**
|
/**
|
||||||
* @constructs
|
* @constructs
|
||||||
* @param id
|
* @param id
|
||||||
* @param version
|
* @param version
|
||||||
* @extends mindplot.model.IMindmap
|
* @extends mindplot.model.IMindmap
|
||||||
*/
|
*/
|
||||||
initialize:function (id, version) {
|
initialize(id, version) {
|
||||||
$assert(id, "Id can not be null");
|
$assert(id, 'Id can not be null');
|
||||||
this._branches = [];
|
this._branches = [];
|
||||||
this._description = null;
|
this._description = null;
|
||||||
this._relationships = [];
|
this._relationships = [];
|
||||||
this._version = $defined(version) ? version : ModelCodeName.TANGO;
|
this._version = $defined(version) ? version : ModelCodeName.TANGO;
|
||||||
this._id = id;
|
this._id = id;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getDescription:function () {
|
getDescription() {
|
||||||
return this._description;
|
return this._description;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setDescription:function (value) {
|
setDescription(value) {
|
||||||
this._description = value;
|
this._description = value;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getId:function () {
|
getId() {
|
||||||
return this._id;
|
return this._id;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setId:function (id) {
|
setId(id) {
|
||||||
this._id = id;
|
this._id = id;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getVersion:function () {
|
getVersion() {
|
||||||
return this._version;
|
return this._version;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setVersion:function (version) {
|
setVersion(version) {
|
||||||
this._version = version;
|
this._version = version;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {mindplot.model.NodeModel} nodeModel
|
* @param {mindplot.model.NodeModel} nodeModel
|
||||||
* @throws will throw an error if nodeModel is null, undefined or not a node model object
|
* @throws will throw an error if nodeModel is null, undefined or not a node model object
|
||||||
* @throws will throw an error if
|
* @throws will throw an error if
|
||||||
*/
|
*/
|
||||||
addBranch:function (nodeModel) {
|
addBranch(nodeModel) {
|
||||||
$assert(nodeModel && nodeModel.isNodeModel(), 'Add node must be invoked with model objects');
|
$assert(nodeModel && nodeModel.isNodeModel(), 'Add node must be invoked with model objects');
|
||||||
var branches = this.getBranches();
|
const branches = this.getBranches();
|
||||||
if (branches.length == 0) {
|
if (branches.length == 0) {
|
||||||
$assert(nodeModel.getType() == INodeModel.CENTRAL_TOPIC_TYPE, "First element must be the central topic");
|
$assert(nodeModel.getType() == INodeModel.CENTRAL_TOPIC_TYPE, 'First element must be the central topic');
|
||||||
nodeModel.setPosition(0, 0);
|
nodeModel.setPosition(0, 0);
|
||||||
} else {
|
} else {
|
||||||
$assert(nodeModel.getType() != INodeModel.CENTRAL_TOPIC_TYPE, "Mindmaps only have one cental topic");
|
$assert(nodeModel.getType() != INodeModel.CENTRAL_TOPIC_TYPE, 'Mindmaps only have one cental topic');
|
||||||
}
|
}
|
||||||
|
|
||||||
this._branches.push(nodeModel);
|
this._branches.push(nodeModel);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param nodeModel
|
* @param nodeModel
|
||||||
*/
|
*/
|
||||||
removeBranch:function (nodeModel) {
|
removeBranch(nodeModel) {
|
||||||
$assert(nodeModel && nodeModel.isNodeModel(), 'Remove node must be invoked with model objects');
|
$assert(nodeModel && nodeModel.isNodeModel(), 'Remove node must be invoked with model objects');
|
||||||
return this._branches.erase(nodeModel);
|
return this._branches.erase(nodeModel);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getBranches:function () {
|
getBranches() {
|
||||||
return this._branches;
|
return this._branches;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getRelationships:function () {
|
getRelationships() {
|
||||||
return this._relationships;
|
return this._relationships;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param node
|
* @param node
|
||||||
* @return {Boolean} true if node already exists
|
* @return {Boolean} true if node already exists
|
||||||
*/
|
*/
|
||||||
hasAlreadyAdded:function (node) {
|
hasAlreadyAdded(node) {
|
||||||
var result = false;
|
let result = false;
|
||||||
|
|
||||||
// Check in not connected nodes.
|
// Check in not connected nodes.
|
||||||
var branches = this._branches;
|
const branches = this._branches;
|
||||||
for (var i = 0; i < branches.length; i++) {
|
for (let i = 0; i < branches.length; i++) {
|
||||||
result = branches[i]._isChildNode(node);
|
result = branches[i]._isChildNode(node);
|
||||||
if (result) {
|
if (result) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param type
|
* @param type
|
||||||
* @param id
|
* @param id
|
||||||
* @return the node model created
|
* @return the node model created
|
||||||
*/
|
*/
|
||||||
createNode:function (type, id) {
|
createNode(type, id) {
|
||||||
type = !$defined(type) ? INodeModel.MAIN_TOPIC_TYPE : type;
|
type = !$defined(type) ? INodeModel.MAIN_TOPIC_TYPE : type;
|
||||||
return new NodeModel(type, this, id);
|
return new NodeModel(type, this, id);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param sourceNodeId
|
* @param sourceNodeId
|
||||||
* @param targetNodeId
|
* @param targetNodeId
|
||||||
* @throws will throw an error if source node is null or undefined
|
* @throws will throw an error if source node is null or undefined
|
||||||
* @throws will throw an error if target node is null or undefined
|
* @throws will throw an error if target node is null or undefined
|
||||||
* @return the relationship model created
|
* @return the relationship model created
|
||||||
*/
|
*/
|
||||||
createRelationship:function (sourceNodeId, targetNodeId) {
|
createRelationship(sourceNodeId, targetNodeId) {
|
||||||
$assert($defined(sourceNodeId), 'from node cannot be null');
|
$assert($defined(sourceNodeId), 'from node cannot be null');
|
||||||
$assert($defined(targetNodeId), 'to node cannot be null');
|
$assert($defined(targetNodeId), 'to node cannot be null');
|
||||||
|
|
||||||
return new RelationshipModel(sourceNodeId, targetNodeId);
|
return new RelationshipModel(sourceNodeId, targetNodeId);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param relationship
|
* @param relationship
|
||||||
*/
|
*/
|
||||||
addRelationship:function (relationship) {
|
addRelationship(relationship) {
|
||||||
this._relationships.push(relationship);
|
this._relationships.push(relationship);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param relationship
|
* @param relationship
|
||||||
*/
|
*/
|
||||||
deleteRelationship:function (relationship) {
|
deleteRelationship(relationship) {
|
||||||
this._relationships.erase(relationship);
|
this._relationships.erase(relationship);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param id
|
* @param id
|
||||||
* @return the node with the respective id or null if not in the mindmap
|
* @return the node with the respective id or null if not in the mindmap
|
||||||
*/
|
*/
|
||||||
findNodeById:function (id) {
|
findNodeById(id) {
|
||||||
var result = null;
|
let result = null;
|
||||||
for (var i = 0; i < this._branches.length; i++) {
|
for (let i = 0; i < this._branches.length; i++) {
|
||||||
var branch = this._branches[i];
|
const branch = this._branches[i];
|
||||||
result = branch.findNodeById(id);
|
result = branch.findNodeById(id);
|
||||||
if (result) {
|
if (result) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
return result;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mapId
|
* @param mapId
|
||||||
* @return an empty mindmap with central topic only
|
* @return an empty mindmap with central topic only
|
||||||
*/
|
*/
|
||||||
Mindmap.buildEmpty = function (mapId) {
|
Mindmap.buildEmpty = function (mapId) {
|
||||||
var result = new Mindmap(mapId);
|
const result = new Mindmap(mapId);
|
||||||
var node = result.createNode(INodeModel.CENTRAL_TOPIC_TYPE, 0);
|
const node = result.createNode(INodeModel.CENTRAL_TOPIC_TYPE, 0);
|
||||||
result.addBranch(node);
|
result.addBranch(node);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Mindmap;
|
export default Mindmap;
|
||||||
|
@ -15,231 +15,224 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
const INodeModel = require('./INodeModel').default
|
const INodeModel = require('./INodeModel').default;
|
||||||
const TopicFeature = require('../TopicFeature').default
|
const TopicFeature = require('../TopicFeature').default;
|
||||||
|
|
||||||
const NodeModel = new Class(/** @lends NodeModel */{
|
const NodeModel = new Class(/** @lends NodeModel */{
|
||||||
Extends:INodeModel,
|
Extends: INodeModel,
|
||||||
/**
|
/**
|
||||||
* @constructs
|
* @constructs
|
||||||
* @param {String} type node type
|
* @param {String} type node type
|
||||||
* @param mindmap
|
* @param mindmap
|
||||||
* @param id
|
* @param id
|
||||||
*/
|
*/
|
||||||
initialize:function (type, mindmap, id) {
|
initialize(type, mindmap, id) {
|
||||||
$assert(type, 'Node type can not be null');
|
$assert(type, 'Node type can not be null');
|
||||||
$assert(mindmap, 'mindmap can not be null');
|
$assert(mindmap, 'mindmap can not be null');
|
||||||
this._properties = {};
|
this._properties = {};
|
||||||
|
|
||||||
this.parent(mindmap);
|
this.parent(mindmap);
|
||||||
this.setId(id);
|
this.setId(id);
|
||||||
this.setType(type);
|
this.setType(type);
|
||||||
this.areChildrenShrunken(false);
|
this.areChildrenShrunken(false);
|
||||||
|
|
||||||
this._children = [];
|
this._children = [];
|
||||||
this._feature = [];
|
this._feature = [];
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param type
|
* @param type
|
||||||
* @param attributes
|
* @param attributes
|
||||||
* @return {mindplot.model.FeatureModel} the created feature model
|
* @return {mindplot.model.FeatureModel} the created feature model
|
||||||
*/
|
*/
|
||||||
createFeature:function (type, attributes) {
|
createFeature(type, attributes) {
|
||||||
return TopicFeature.createModel(type, attributes);
|
return TopicFeature.createModel(type, attributes);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param feature
|
* @param feature
|
||||||
* @throws will throw an error if feature is null or undefined
|
* @throws will throw an error if feature is null or undefined
|
||||||
*/
|
*/
|
||||||
addFeature:function (feature) {
|
addFeature(feature) {
|
||||||
$assert(feature, 'feature can not be null');
|
$assert(feature, 'feature can not be null');
|
||||||
this._feature.push(feature);
|
this._feature.push(feature);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getFeatures:function () {
|
getFeatures() {
|
||||||
return this._feature;
|
return this._feature;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param feature
|
* @param feature
|
||||||
* @throws will throw an error if feature is null or undefined
|
* @throws will throw an error if feature is null or undefined
|
||||||
* @throws will throw an error if the feature could not be removed
|
* @throws will throw an error if the feature could not be removed
|
||||||
*/
|
*/
|
||||||
removeFeature:function (feature) {
|
removeFeature(feature) {
|
||||||
$assert(feature, 'feature can not be null');
|
$assert(feature, 'feature can not be null');
|
||||||
var size = this._feature.length;
|
const size = this._feature.length;
|
||||||
this._feature = this._feature.filter(function (f) {
|
this._feature = this._feature.filter((f) => feature.getId() != f.getId());
|
||||||
return feature.getId() != f.getId();
|
$assert(size - 1 == this._feature.length, 'Could not be removed ...');
|
||||||
});
|
},
|
||||||
$assert(size - 1 == this._feature.length, 'Could not be removed ...');
|
|
||||||
|
|
||||||
},
|
/**
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {String} type the feature type, e.g. icon or link
|
* @param {String} type the feature type, e.g. icon or link
|
||||||
* @throws will throw an error if type is null or undefined
|
* @throws will throw an error if type is null or undefined
|
||||||
*/
|
*/
|
||||||
findFeatureByType:function (type) {
|
findFeatureByType(type) {
|
||||||
$assert(type, 'type can not be null');
|
$assert(type, 'type can not be null');
|
||||||
return this._feature.filter(function (feature) {
|
return this._feature.filter((feature) => feature.getType() == type);
|
||||||
return feature.getType() == type;
|
},
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {String} id
|
* @param {String} id
|
||||||
* @throws will throw an error if id is null or undefined
|
* @throws will throw an error if id is null or undefined
|
||||||
* @throws will throw an error if feature could not be found
|
* @throws will throw an error if feature could not be found
|
||||||
* @return the feature with the given id
|
* @return the feature with the given id
|
||||||
*/
|
*/
|
||||||
findFeatureById:function (id) {
|
findFeatureById(id) {
|
||||||
$assert($defined(id), 'id can not be null');
|
$assert($defined(id), 'id can not be null');
|
||||||
var result = this._feature.filter(function (feature) {
|
const result = this._feature.filter((feature) => feature.getId() == id);
|
||||||
return feature.getId() == id;
|
$assert(result.length == 1, `Feature could not be found:${id}`);
|
||||||
});
|
return result[0];
|
||||||
$assert(result.length == 1, "Feature could not be found:" + id);
|
},
|
||||||
return result[0];
|
|
||||||
},
|
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getPropertiesKeys:function () {
|
getPropertiesKeys() {
|
||||||
return Object.keys(this._properties);
|
return Object.keys(this._properties);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param key
|
* @param key
|
||||||
* @param value
|
* @param value
|
||||||
* @throws will throw an error if key is null or undefined
|
* @throws will throw an error if key is null or undefined
|
||||||
*/
|
*/
|
||||||
putProperty:function (key, value) {
|
putProperty(key, value) {
|
||||||
$defined(key, 'key can not be null');
|
$defined(key, 'key can not be null');
|
||||||
this._properties[key] = value;
|
this._properties[key] = value;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getProperties:function () {
|
getProperties() {
|
||||||
return this._properties;
|
return this._properties;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getProperty:function (key) {
|
getProperty(key) {
|
||||||
$defined(key, 'key can not be null');
|
$defined(key, 'key can not be null');
|
||||||
var result = this._properties[key];
|
const result = this._properties[key];
|
||||||
return !$defined(result) ? null : result;
|
return !$defined(result) ? null : result;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {mindplot.model.NodeModel} an identical clone of the NodeModel
|
* @return {mindplot.model.NodeModel} an identical clone of the NodeModel
|
||||||
*/
|
*/
|
||||||
clone:function () {
|
clone() {
|
||||||
var result = new NodeModel(this.getType(), this._mindmap);
|
const result = new NodeModel(this.getType(), this._mindmap);
|
||||||
result._children = this._children.map(function (node) {
|
result._children = this._children.map((node) => {
|
||||||
var cnode = node.clone();
|
const cnode = node.clone();
|
||||||
cnode._parent = result;
|
cnode._parent = result;
|
||||||
return cnode;
|
return cnode;
|
||||||
});
|
});
|
||||||
|
|
||||||
result._properties = Object.clone(this._properties);
|
result._properties = Object.clone(this._properties);
|
||||||
result._feature = this._feature.clone();
|
result._feature = this._feature.clone();
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Similar to clone, assign new id to the elements ...
|
* Similar to clone, assign new id to the elements ...
|
||||||
* @return {mindplot.model.NodeModel}
|
* @return {mindplot.model.NodeModel}
|
||||||
*/
|
*/
|
||||||
deepCopy:function () {
|
deepCopy() {
|
||||||
var result = new NodeModel(this.getType(), this._mindmap);
|
const result = new NodeModel(this.getType(), this._mindmap);
|
||||||
result._children = this._children.map(function (node) {
|
result._children = this._children.map((node) => {
|
||||||
var cnode = node.deepCopy();
|
const cnode = node.deepCopy();
|
||||||
cnode._parent = result;
|
cnode._parent = result;
|
||||||
return cnode;
|
return cnode;
|
||||||
});
|
});
|
||||||
|
|
||||||
var id = result.getId();
|
const id = result.getId();
|
||||||
result._properties = Object.clone(this._properties);
|
result._properties = Object.clone(this._properties);
|
||||||
result.setId(id);
|
result.setId(id);
|
||||||
|
|
||||||
result._feature = this._feature.clone();
|
result._feature = this._feature.clone();
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {mindplot.model.NodeModel} child
|
* @param {mindplot.model.NodeModel} child
|
||||||
* @throws will throw an error if child is null, undefined or not a NodeModel object
|
* @throws will throw an error if child is null, undefined or not a NodeModel object
|
||||||
*/
|
*/
|
||||||
append:function (child) {
|
append(child) {
|
||||||
$assert(child && child.isNodeModel(), 'Only NodeModel can be appended to Mindmap object');
|
$assert(child && child.isNodeModel(), 'Only NodeModel can be appended to Mindmap object');
|
||||||
this._children.push(child);
|
this._children.push(child);
|
||||||
child._parent = this;
|
child._parent = this;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {mindplot.model.NodeModel} child
|
* @param {mindplot.model.NodeModel} child
|
||||||
* @throws will throw an error if child is null, undefined or not a NodeModel object
|
* @throws will throw an error if child is null, undefined or not a NodeModel object
|
||||||
*/
|
*/
|
||||||
removeChild:function (child) {
|
removeChild(child) {
|
||||||
$assert(child && child.isNodeModel(), 'Only NodeModel can be appended to Mindmap object.');
|
$assert(child && child.isNodeModel(), 'Only NodeModel can be appended to Mindmap object.');
|
||||||
this._children.erase(child);
|
this._children.erase(child);
|
||||||
child._parent = null;
|
child._parent = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getChildren:function () {
|
getChildren() {
|
||||||
return this._children;
|
return this._children;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getParent:function () {
|
getParent() {
|
||||||
return this._parent;
|
return this._parent;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setParent:function (parent) {
|
setParent(parent) {
|
||||||
$assert(parent != this, 'The same node can not be parent and child if itself.');
|
$assert(parent != this, 'The same node can not be parent and child if itself.');
|
||||||
this._parent = parent;
|
this._parent = parent;
|
||||||
},
|
},
|
||||||
|
|
||||||
_isChildNode:function (node) {
|
_isChildNode(node) {
|
||||||
var result = false;
|
let result = false;
|
||||||
if (node == this) {
|
if (node == this) {
|
||||||
result = true;
|
result = true;
|
||||||
} else {
|
} else {
|
||||||
var children = this.getChildren();
|
const children = this.getChildren();
|
||||||
for (var i = 0; i < children.length; i++) {
|
for (let i = 0; i < children.length; i++) {
|
||||||
var child = children[i];
|
const child = children[i];
|
||||||
result = child._isChildNode(node);
|
result = child._isChildNode(node);
|
||||||
if (result) {
|
if (result) {
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
}
|
||||||
},
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @id
|
* @id
|
||||||
* @return {mindplot.model.NodeModel} the node with the respective id
|
* @return {mindplot.model.NodeModel} the node with the respective id
|
||||||
*/
|
*/
|
||||||
findNodeById:function (id) {
|
findNodeById(id) {
|
||||||
var result = null;
|
let result = null;
|
||||||
if (this.getId() == id) {
|
if (this.getId() == id) {
|
||||||
result = this;
|
result = this;
|
||||||
} else {
|
} else {
|
||||||
var children = this.getChildren();
|
const children = this.getChildren();
|
||||||
for (var i = 0; i < children.length; i++) {
|
for (let i = 0; i < children.length; i++) {
|
||||||
var child = children[i];
|
const child = children[i];
|
||||||
result = child.findNodeById(id);
|
result = child.findNodeById(id);
|
||||||
if (result) {
|
if (result) {
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
}
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default NodeModel
|
export default NodeModel;
|
||||||
|
@ -15,31 +15,31 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
const FeatureModel = require('./FeatureModel').default
|
const FeatureModel = require('./FeatureModel').default;
|
||||||
|
|
||||||
const NoteModel = new Class(/** @lends NoteModel */{
|
const NoteModel = new Class(/** @lends NoteModel */{
|
||||||
Extends:FeatureModel,
|
Extends: FeatureModel,
|
||||||
/**
|
/**
|
||||||
* @constructs
|
* @constructs
|
||||||
* @param attributes
|
* @param attributes
|
||||||
* @extends mindplot.model.FeatureModel
|
* @extends mindplot.model.FeatureModel
|
||||||
*/
|
*/
|
||||||
initialize:function (attributes) {
|
initialize(attributes) {
|
||||||
this.parent(NoteModel.FEATURE_TYPE);
|
this.parent(NoteModel.FEATURE_TYPE);
|
||||||
var noteText = attributes.text ? attributes.text : " ";
|
const noteText = attributes.text ? attributes.text : ' ';
|
||||||
this.setText(noteText);
|
this.setText(noteText);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getText:function () {
|
getText() {
|
||||||
return this.getAttribute('text');
|
return this.getAttribute('text');
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setText:function (text) {
|
setText(text) {
|
||||||
$assert(text, 'text can not be null');
|
$assert(text, 'text can not be null');
|
||||||
this.setAttribute('text', text);
|
this.setAttribute('text', text);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,6 +47,6 @@ const NoteModel = new Class(/** @lends NoteModel */{
|
|||||||
* @type {String}
|
* @type {String}
|
||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
NoteModel.FEATURE_TYPE = "note";
|
NoteModel.FEATURE_TYPE = 'note';
|
||||||
|
|
||||||
export default NoteModel;
|
export default NoteModel;
|
||||||
|
@ -18,131 +18,131 @@
|
|||||||
const ConnectionLine = require('../ConnectionLine').default;
|
const ConnectionLine = require('../ConnectionLine').default;
|
||||||
|
|
||||||
const RelationshipModel = new Class(
|
const RelationshipModel = new Class(
|
||||||
/** @lends RelationshipModel */ {
|
/** @lends RelationshipModel */ {
|
||||||
Static: {
|
Static: {
|
||||||
_nextUUID: function () {
|
_nextUUID() {
|
||||||
if (!$defined(RelationshipModel._uuid)) {
|
if (!$defined(RelationshipModel._uuid)) {
|
||||||
RelationshipModel._uuid = 0;
|
RelationshipModel._uuid = 0;
|
||||||
}
|
}
|
||||||
RelationshipModel._uuid = RelationshipModel._uuid + 1;
|
RelationshipModel._uuid += 1;
|
||||||
return RelationshipModel._uuid;
|
return RelationshipModel._uuid;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructs
|
* @constructs
|
||||||
* @param sourceTopicId
|
* @param sourceTopicId
|
||||||
* @param targetTopicId
|
* @param targetTopicId
|
||||||
* @throws will throw an error if sourceTopicId is null or undefined
|
* @throws will throw an error if sourceTopicId is null or undefined
|
||||||
* @throws will throw an error if targetTopicId is null or undefined
|
* @throws will throw an error if targetTopicId is null or undefined
|
||||||
*/
|
*/
|
||||||
initialize: function (sourceTopicId, targetTopicId) {
|
initialize(sourceTopicId, targetTopicId) {
|
||||||
$assert($defined(sourceTopicId), 'from node type can not be null');
|
$assert($defined(sourceTopicId), 'from node type can not be null');
|
||||||
$assert($defined(targetTopicId), 'to node type can not be null');
|
$assert($defined(targetTopicId), 'to node type can not be null');
|
||||||
|
|
||||||
this._id = RelationshipModel._nextUUID();
|
this._id = RelationshipModel._nextUUID();
|
||||||
this._sourceTargetId = sourceTopicId;
|
this._sourceTargetId = sourceTopicId;
|
||||||
this._targetTopicId = targetTopicId;
|
this._targetTopicId = targetTopicId;
|
||||||
this._lineType = ConnectionLine.SIMPLE_CURVED;
|
this._lineType = ConnectionLine.SIMPLE_CURVED;
|
||||||
this._srcCtrlPoint = null;
|
this._srcCtrlPoint = null;
|
||||||
this._destCtrlPoint = null;
|
this._destCtrlPoint = null;
|
||||||
this._endArrow = true;
|
this._endArrow = true;
|
||||||
this._startArrow = false;
|
this._startArrow = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getFromNode: function () {
|
getFromNode() {
|
||||||
return this._sourceTargetId;
|
return this._sourceTargetId;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getToNode: function () {
|
getToNode() {
|
||||||
return this._targetTopicId;
|
return this._targetTopicId;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getId: function () {
|
getId() {
|
||||||
$assert(this._id, 'id is null');
|
$assert(this._id, 'id is null');
|
||||||
return this._id;
|
return this._id;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getLineType: function () {
|
getLineType() {
|
||||||
return this._lineType;
|
return this._lineType;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setLineType: function (lineType) {
|
setLineType(lineType) {
|
||||||
this._lineType = lineType;
|
this._lineType = lineType;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getSrcCtrlPoint: function () {
|
getSrcCtrlPoint() {
|
||||||
return this._srcCtrlPoint;
|
return this._srcCtrlPoint;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setSrcCtrlPoint: function (srcCtrlPoint) {
|
setSrcCtrlPoint(srcCtrlPoint) {
|
||||||
this._srcCtrlPoint = srcCtrlPoint;
|
this._srcCtrlPoint = srcCtrlPoint;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getDestCtrlPoint: function () {
|
getDestCtrlPoint() {
|
||||||
return this._destCtrlPoint;
|
return this._destCtrlPoint;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setDestCtrlPoint: function (destCtrlPoint) {
|
setDestCtrlPoint(destCtrlPoint) {
|
||||||
this._destCtrlPoint = destCtrlPoint;
|
this._destCtrlPoint = destCtrlPoint;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getEndArrow: function () {
|
getEndArrow() {
|
||||||
return this._endArrow;
|
return this._endArrow;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setEndArrow: function (endArrow) {
|
setEndArrow(endArrow) {
|
||||||
this._endArrow = endArrow;
|
this._endArrow = endArrow;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getStartArrow: function () {
|
getStartArrow() {
|
||||||
return this._startArrow;
|
return this._startArrow;
|
||||||
},
|
},
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setStartArrow: function (startArrow) {
|
setStartArrow(startArrow) {
|
||||||
this._startArrow = startArrow;
|
this._startArrow = startArrow;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a clone of the relationship model
|
* @return a clone of the relationship model
|
||||||
*/
|
*/
|
||||||
clone: function () {
|
clone() {
|
||||||
var result = new RelationshipModel(this._sourceTargetId, this._targetTopicId);
|
const result = new RelationshipModel(this._sourceTargetId, this._targetTopicId);
|
||||||
result._id = this._id;
|
result._id = this._id;
|
||||||
result._lineType = this._lineType;
|
result._lineType = this._lineType;
|
||||||
result._srcCtrlPoint = this._srcCtrlPoint;
|
result._srcCtrlPoint = this._srcCtrlPoint;
|
||||||
result._destCtrlPoint = this._destCtrlPoint;
|
result._destCtrlPoint = this._destCtrlPoint;
|
||||||
result._endArrow = this._endArrow;
|
result._endArrow = this._endArrow;
|
||||||
result._startArrow = this._startArrow;
|
result._startArrow = this._startArrow;
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {String} textual information about the relationship's source and target node
|
* @return {String} textual information about the relationship's source and target node
|
||||||
*/
|
*/
|
||||||
inspect: function () {
|
inspect() {
|
||||||
return (
|
return (
|
||||||
'(fromNode:' +
|
`(fromNode:${
|
||||||
this.getFromNode().getId() +
|
this.getFromNode().getId()
|
||||||
' , toNode: ' +
|
} , toNode: ${
|
||||||
this.getToNode().getId() +
|
this.getToNode().getId()
|
||||||
')'
|
})`
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
export default RelationshipModel;
|
export default RelationshipModel;
|
||||||
|
@ -9,13 +9,13 @@ const nodeModel = require('./NodeModel').default;
|
|||||||
const relationshipModel = require('./RelationshipModel').default;
|
const relationshipModel = require('./RelationshipModel').default;
|
||||||
|
|
||||||
export const Model = {
|
export const Model = {
|
||||||
FeatureModel: featureModel,
|
FeatureModel: featureModel,
|
||||||
IconModel: iconModel,
|
IconModel: iconModel,
|
||||||
IMindmap: iMindmap,
|
IMindmap: iMindmap,
|
||||||
INodeModel: iNodeModel,
|
INodeModel: iNodeModel,
|
||||||
LinkModel: linkModel,
|
LinkModel: linkModel,
|
||||||
NoteModel: noteModel,
|
NoteModel: noteModel,
|
||||||
Mindmap: mindmap,
|
Mindmap: mindmap,
|
||||||
NodeModel: nodeModel,
|
NodeModel: nodeModel,
|
||||||
RelationshipModel: relationshipModel,
|
RelationshipModel: relationshipModel,
|
||||||
};
|
};
|
||||||
|
@ -15,45 +15,45 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
const ModelCodeName = require('./ModelCodeName').default
|
const ModelCodeName = require('./ModelCodeName').default;
|
||||||
const XMLSerializer_Pela = require('./XMLSerializer_Pela').default;
|
const XMLSerializer_Pela = require('./XMLSerializer_Pela').default;
|
||||||
|
|
||||||
const Beta2PelaMigrator = new Class({
|
const Beta2PelaMigrator = new Class({
|
||||||
initialize:function (betaSerializer) {
|
initialize(betaSerializer) {
|
||||||
this._betaSerializer = betaSerializer;
|
this._betaSerializer = betaSerializer;
|
||||||
this._pelaSerializer = new XMLSerializer_Pela();
|
this._pelaSerializer = new XMLSerializer_Pela();
|
||||||
},
|
},
|
||||||
|
|
||||||
toXML:function (mindmap) {
|
toXML(mindmap) {
|
||||||
return this._pelaSerializer.toXML(mindmap);
|
return this._pelaSerializer.toXML(mindmap);
|
||||||
},
|
},
|
||||||
|
|
||||||
loadFromDom:function (dom, mapId) {
|
loadFromDom(dom, mapId) {
|
||||||
$assert($defined(mapId), "mapId can not be null");
|
$assert($defined(mapId), 'mapId can not be null');
|
||||||
var mindmap = this._betaSerializer.loadFromDom(dom, mapId);
|
const mindmap = this._betaSerializer.loadFromDom(dom, mapId);
|
||||||
mindmap.setVersion(ModelCodeName.PELA);
|
mindmap.setVersion(ModelCodeName.PELA);
|
||||||
|
|
||||||
// Beta does not set position on second level nodes ...
|
// Beta does not set position on second level nodes ...
|
||||||
var branches = mindmap.getBranches();
|
const branches = mindmap.getBranches();
|
||||||
var me = this;
|
const me = this;
|
||||||
_.each(branches, function (model) {
|
_.each(branches, (model) => {
|
||||||
me._fixPosition(model);
|
me._fixPosition(model);
|
||||||
});
|
});
|
||||||
|
|
||||||
return mindmap;
|
return mindmap;
|
||||||
},
|
},
|
||||||
|
|
||||||
_fixPosition:function (parentModel) {
|
_fixPosition(parentModel) {
|
||||||
var parentPos = parentModel.getPosition();
|
const parentPos = parentModel.getPosition();
|
||||||
var isRight = parentPos.x > 0;
|
const isRight = parentPos.x > 0;
|
||||||
var me = this;
|
const me = this;
|
||||||
_.each(parentModel.getChildren(), function (child) {
|
_.each(parentModel.getChildren(), (child) => {
|
||||||
if (!child.getPosition()) {
|
if (!child.getPosition()) {
|
||||||
child.setPosition(parentPos.x + (50 * isRight ? 1 : -1), parentPos.y);
|
child.setPosition(parentPos.x + (50 * isRight ? 1 : -1), parentPos.y);
|
||||||
}
|
}
|
||||||
me._fixPosition(child);
|
me._fixPosition(child);
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default Beta2PelaMigrator;
|
export default Beta2PelaMigrator;
|
||||||
|
@ -21,9 +21,9 @@
|
|||||||
* @enum {String}
|
* @enum {String}
|
||||||
*/
|
*/
|
||||||
const ModelCodeName = {
|
const ModelCodeName = {
|
||||||
BETA : "beta",
|
BETA: 'beta',
|
||||||
PELA : "pela",
|
PELA: 'pela',
|
||||||
TANGO : "tango"
|
TANGO: 'tango',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ModelCodeName
|
export default ModelCodeName;
|
||||||
|
@ -15,85 +15,78 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
const XMLSerializer_Tango = require('./XMLSerializer_Tango').default
|
const XMLSerializer_Tango = require('./XMLSerializer_Tango').default;
|
||||||
const ModelCodeName = require('./ModelCodeName').default;
|
const ModelCodeName = require('./ModelCodeName').default;
|
||||||
|
|
||||||
const Pela2TangoMigrator = new Class({
|
const Pela2TangoMigrator = new Class({
|
||||||
initialize : function(pelaSerializer) {
|
initialize(pelaSerializer) {
|
||||||
this._pelaSerializer = pelaSerializer;
|
this._pelaSerializer = pelaSerializer;
|
||||||
this._tangoSerializer = new XMLSerializer_Tango();
|
this._tangoSerializer = new XMLSerializer_Tango();
|
||||||
},
|
},
|
||||||
|
|
||||||
toXML : function(mindmap) {
|
toXML(mindmap) {
|
||||||
return this._tangoSerializer.toXML(mindmap);
|
return this._tangoSerializer.toXML(mindmap);
|
||||||
},
|
},
|
||||||
|
|
||||||
loadFromDom : function(dom, mapId) {
|
loadFromDom(dom, mapId) {
|
||||||
$assert($defined(mapId), "mapId can not be null");
|
$assert($defined(mapId), 'mapId can not be null');
|
||||||
var mindmap = this._pelaSerializer.loadFromDom(dom, mapId);
|
const mindmap = this._pelaSerializer.loadFromDom(dom, mapId);
|
||||||
mindmap.setVersion(ModelCodeName.TANGO);
|
mindmap.setVersion(ModelCodeName.TANGO);
|
||||||
this._fixOrder(mindmap);
|
this._fixOrder(mindmap);
|
||||||
this._fixPosition(mindmap);
|
this._fixPosition(mindmap);
|
||||||
return mindmap;
|
return mindmap;
|
||||||
},
|
},
|
||||||
|
|
||||||
_fixOrder : function(mindmap) {
|
|
||||||
// First level node policies has been changed.
|
|
||||||
var centralNode = mindmap.getBranches()[0];
|
|
||||||
var children = centralNode.getChildren();
|
|
||||||
var leftNodes = [];
|
|
||||||
var rightNodes = [];
|
|
||||||
for (var i = 0; i < children.length; i++) {
|
|
||||||
var child = children[i];
|
|
||||||
var position = child.getPosition();
|
|
||||||
if (position.x < 0) {
|
|
||||||
leftNodes.push(child);
|
|
||||||
} else {
|
|
||||||
rightNodes.push(child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rightNodes.sort(function(a, b) {
|
|
||||||
return a.getOrder() > b.getOrder()
|
|
||||||
});
|
|
||||||
leftNodes.sort(function(a, b) {
|
|
||||||
return a.getOrder() > b.getOrder();
|
|
||||||
});
|
|
||||||
|
|
||||||
for (i = 0; i < rightNodes.length; i++) {
|
|
||||||
rightNodes[i].setOrder(i * 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < leftNodes.length; i++) {
|
|
||||||
leftNodes[i].setOrder(i * 2 + 1);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_fixPosition : function(mindmap) {
|
|
||||||
// Position was not required in previous versions. Try to synthesize one .
|
|
||||||
var centralNode = mindmap.getBranches()[0];
|
|
||||||
var children = centralNode.getChildren();
|
|
||||||
for (var i = 0; i < children.length; i++) {
|
|
||||||
var child = children[i];
|
|
||||||
var position = child.getPosition();
|
|
||||||
this._fixNodePosition(child, position)
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_fixNodePosition : function(node, parentPosition) {
|
|
||||||
// Position was not required in previous versions. Try to synthesize one .
|
|
||||||
var position = node.getPosition();
|
|
||||||
if (!position) {
|
|
||||||
position = {x:parentPosition.x + 30,y:parentPosition.y};
|
|
||||||
node.setPosition(position.x, position.y);
|
|
||||||
}
|
|
||||||
var children = node.getChildren();
|
|
||||||
for (var i = 0; i < children.length; i++) {
|
|
||||||
var child = children[i];
|
|
||||||
this._fixNodePosition(child, position);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
_fixOrder(mindmap) {
|
||||||
|
// First level node policies has been changed.
|
||||||
|
const centralNode = mindmap.getBranches()[0];
|
||||||
|
const children = centralNode.getChildren();
|
||||||
|
const leftNodes = [];
|
||||||
|
const rightNodes = [];
|
||||||
|
for (var i = 0; i < children.length; i++) {
|
||||||
|
const child = children[i];
|
||||||
|
const position = child.getPosition();
|
||||||
|
if (position.x < 0) {
|
||||||
|
leftNodes.push(child);
|
||||||
|
} else {
|
||||||
|
rightNodes.push(child);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
rightNodes.sort((a, b) => a.getOrder() > b.getOrder());
|
||||||
|
leftNodes.sort((a, b) => a.getOrder() > b.getOrder());
|
||||||
|
|
||||||
|
for (i = 0; i < rightNodes.length; i++) {
|
||||||
|
rightNodes[i].setOrder(i * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < leftNodes.length; i++) {
|
||||||
|
leftNodes[i].setOrder(i * 2 + 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_fixPosition(mindmap) {
|
||||||
|
// Position was not required in previous versions. Try to synthesize one .
|
||||||
|
const centralNode = mindmap.getBranches()[0];
|
||||||
|
const children = centralNode.getChildren();
|
||||||
|
for (let i = 0; i < children.length; i++) {
|
||||||
|
const child = children[i];
|
||||||
|
const position = child.getPosition();
|
||||||
|
this._fixNodePosition(child, position);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_fixNodePosition(node, parentPosition) {
|
||||||
|
// Position was not required in previous versions. Try to synthesize one .
|
||||||
|
let position = node.getPosition();
|
||||||
|
if (!position) {
|
||||||
|
position = { x: parentPosition.x + 30, y: parentPosition.y };
|
||||||
|
node.setPosition(position.x, position.y);
|
||||||
|
}
|
||||||
|
const children = node.getChildren();
|
||||||
|
for (let i = 0; i < children.length; i++) {
|
||||||
|
const child = children[i];
|
||||||
|
this._fixNodePosition(child, position);
|
||||||
|
}
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default Pela2TangoMigrator;
|
export default Pela2TangoMigrator;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user