working on Freemind layout algorithm

This commit is contained in:
Pablo Luna 2011-04-08 15:31:40 +01:00
parent ae071f7fcb
commit d4de03d373
20 changed files with 472 additions and 144 deletions

View File

@ -124,6 +124,8 @@
files="commands/AddRelationshipCommand.js"/> files="commands/AddRelationshipCommand.js"/>
<filelist dir="${basedir}/src/main/javascript/" <filelist dir="${basedir}/src/main/javascript/"
files="commands/MoveControlPointCommand.js"/> files="commands/MoveControlPointCommand.js"/>
<filelist dir="${basedir}/src/main/javascript/"
files="commands/freeMind/DragTopicCommand.js"/>
<filelist dir="${basedir}/src/main/javascript/" <filelist dir="${basedir}/src/main/javascript/"
@ -241,6 +243,7 @@
<include>commands/RemoveNoteFromTopicCommand-min.js</include> <include>commands/RemoveNoteFromTopicCommand-min.js</include>
<include>commands/AddRelationshipCommand-min.js</include> <include>commands/AddRelationshipCommand-min.js</include>
<include>commands/MoveControlPointCommand-min.js</include> <include>commands/MoveControlPointCommand-min.js</include>
<include>commands/freeMind/DragTopicCommand-min.js</include>
<include>layoutManagers/boards/Board-min.js</include> <include>layoutManagers/boards/Board-min.js</include>
<include>layoutManagers/boards/freeMindBoards/Board-min.js</include> <include>layoutManagers/boards/freeMindBoards/Board-min.js</include>

View File

@ -87,7 +87,7 @@ mindplot.CentralTopic.prototype.updateTopicShape = function()
{ {
}; };
mindplot.CentralTopic.prototype._updatePositionOnChangeSize = function(oldSize, newSize) { mindplot.CentralTopic.prototype._updatePositionOnChangeSize = function(oldSize, newSize, updatePosition) {
// Center main topic ... // Center main topic ...
var zeroPoint = new core.Point(0, 0); var zeroPoint = new core.Point(0, 0);

View File

@ -103,7 +103,7 @@ mindplot.CentralTopicBoard.prototype.addBranch = function(topic)
board.update(entry); board.update(entry);
}; };
mindplot.CentralTopicBoard.prototype.updateChildrenPosition = function(topic, xOffset) mindplot.CentralTopicBoard.prototype.updateChildrenPosition = function(topic, xOffset, modifiedTopics)
{ {
var board = this._rightBoard; var board = this._rightBoard;
var oldReferencePosition = board.getReferencePoint(); var oldReferencePosition = board.getReferencePoint();

View File

@ -141,7 +141,7 @@ mindplot.ConnectionLine.prototype._positionateConnector = function(targetTopic)
y = y - offset; y = y - offset;
var connector = targetTopic.getShrinkConnector(); var connector = targetTopic.getShrinkConnector();
if (targetPosition.x >= 0) if (Math.sign(targetPosition.x) > 0)
{ {
var x = targetTopicSize.width; var x = targetTopicSize.width;
connector.setPosition(x, y); connector.setPosition(x, y);

View File

@ -97,10 +97,6 @@ mindplot.CommandContext = new Class({
core.assert(model, "model can not be null"); core.assert(model, "model can not be null");
var topic = this._designer._nodeModelToNodeGraph(model, isVisible); var topic = this._designer._nodeModelToNodeGraph(model, isVisible);
// @todo: Is this required ?
var designer = this._designer;
designer.onObjectFocusEvent.attempt(topic, designer);
return topic; return topic;
}, },
createModel:function() createModel:function()

View File

@ -207,7 +207,7 @@ mindplot.DragTopic.prototype.updateDraggedTopic = function(workspace)
command = new mindplot.commands.DragTopicCommand(topicId, dragPosition); command = new mindplot.commands.DragTopicCommand(topicId, dragPosition);
command.setPosition(dragPosition); command.setPosition(dragPosition);
} }
actionRunner.execute(command) actionRunner.execute(command);
}; };
mindplot.DragTopic.prototype.setBoardPosition = function(point) mindplot.DragTopic.prototype.setBoardPosition = function(point)

View File

@ -175,20 +175,25 @@ mindplot.MainTopic.prototype.getTopicType = function()
}; };
mindplot.MainTopic.prototype._updatePositionOnChangeSize = function(oldSize, newSize) { mindplot.MainTopic.prototype._updatePositionOnChangeSize = function(oldSize, newSize, updatePosition) {
var xOffset = (newSize.width - oldSize.width) / 2; if(!updatePosition && this.getModel().getFinalPosition()){
var pos = this.getPosition(); this.setPosition(this.getModel().getFinalPosition(), false);
if (core.Utils.isDefined(pos)) }
{ else{
if (pos.x > 0) var xOffset = Math.round((newSize.width - oldSize.width) / 2);
var pos = this.getPosition();
if (core.Utils.isDefined(pos))
{ {
pos.x = pos.x + xOffset; if (pos.x > 0)
} else {
{ pos.x = pos.x + xOffset;
pos.x = pos.x - xOffset; } else
{
pos.x = pos.x - xOffset;
}
this.setPosition(pos);
} }
this.setPosition(pos);
} }
}; };

View File

@ -126,16 +126,16 @@ mindplot.Mindmap.prototype.hasAlreadyAdded = function(node)
} }
}; };
mindplot.Mindmap.prototype.createNode = function(type) mindplot.Mindmap.prototype.createNode = function(type, id)
{ {
core.assert(type, "node type can not be null"); core.assert(type, "node type can not be null");
return this._createNode(type); return this._createNode(type, id);
}; };
mindplot.Mindmap.prototype._createNode = function(type) mindplot.Mindmap.prototype._createNode = function(type, id)
{ {
core.assert(type, 'Node type must be specified.'); core.assert(type, 'Node type must be specified.');
var result = new mindplot.NodeModel(type, this); var result = new mindplot.NodeModel(type, this, id);
return result; return result;
}; };

View File

@ -16,7 +16,7 @@
* limitations under the License. * limitations under the License.
*/ */
mindplot.NodeModel = function(type, mindmap) mindplot.NodeModel = function(type, mindmap, id)
{ {
core.assert(type, 'Node type can not be null'); core.assert(type, 'Node type can not be null');
core.assert(mindmap, 'mindmap can not be null'); core.assert(mindmap, 'mindmap can not be null');
@ -29,7 +29,14 @@ mindplot.NodeModel = function(type, mindmap)
this._notes = []; this._notes = [];
this._size = {width:50,height:20}; this._size = {width:50,height:20};
this._position = null; this._position = null;
this._id = mindplot.NodeModel._nextUUID(); if(core.Utils.isDefined(id)){
if(!mindplot.NodeModel._uuid || id>mindplot.NodeModel._uuid){
mindplot.NodeModel._uuid = id;
}
this._id = id;
} else {
this._id = mindplot.NodeModel._nextUUID();
}
this._mindmap = mindmap; this._mindmap = mindmap;
this._text = null; this._text = null;
this._shapeType = null; this._shapeType = null;
@ -95,6 +102,9 @@ mindplot.NodeModel.prototype.getId = function()
mindplot.NodeModel.prototype.setId = function(id) mindplot.NodeModel.prototype.setId = function(id)
{ {
this._id = id; this._id = id;
if(mindplot.NodeModel._uuid<id){
mindplot.NodeModel._uuid = id;
}
}; };
mindplot.NodeModel.prototype.getType = function() mindplot.NodeModel.prototype.getType = function()
@ -213,6 +223,24 @@ mindplot.NodeModel.prototype.getPosition = function()
return this._position; return this._position;
}; };
mindplot.NodeModel.prototype.setFinalPosition = function(x, y)
{
core.assert(core.Utils.isDefined(x), "x coordinate must be defined");
core.assert(core.Utils.isDefined(y), "y coordinate must be defined");
if (!core.Utils.isDefined(this._finalPosition))
{
this._finalPosition = new core.Point();
}
this._finalPosition.x = parseInt(x);
this._finalPosition.y = parseInt(y);
};
mindplot.NodeModel.prototype.getFinalPosition = function()
{
return this._finalPosition;
};
mindplot.NodeModel.prototype.setSize = function(width, height) mindplot.NodeModel.prototype.setSize = function(width, height)
{ {
this._size.width = width; this._size.width = width;

View File

@ -516,7 +516,7 @@ mindplot.Topic.prototype.setFontFamily = function(value, updateModel)
{ {
return function() return function()
{ {
elem.updateNode(); elem.updateNode(updateModel);
}; };
}; };
@ -537,7 +537,7 @@ mindplot.Topic.prototype.setFontSize = function(value, updateModel)
{ {
return function() return function()
{ {
elem.updateNode(); elem.updateNode(updateModel);
}; };
}; };
@ -559,7 +559,7 @@ mindplot.Topic.prototype.setFontStyle = function(value, updateModel)
{ {
return function() return function()
{ {
elem.updateNode(); elem.updateNode(updateModel);
}; };
}; };
@ -657,7 +657,7 @@ mindplot.Topic.prototype._setText = function(text, updateModel)
{ {
return function() return function()
{ {
elem.updateNode(); elem.updateNode(updateModel);
}; };
}; };
@ -1092,7 +1092,7 @@ mindplot.Topic.prototype._setSize = function(size)
innerShape.setSize(size.width, size.height); innerShape.setSize(size.width, size.height);
}; };
mindplot.Topic.prototype.setSize = function(size, force) mindplot.Topic.prototype.setSize = function(size, force, updatePosition)
{ {
var oldSize = this.getSize(); var oldSize = this.getSize();
if (oldSize.width != size.width || oldSize.height != size.height || force) if (oldSize.width != size.width || oldSize.height != size.height || force)
@ -1100,14 +1100,14 @@ mindplot.Topic.prototype.setSize = function(size, force)
this._setSize(size); this._setSize(size);
// Update the figure position(ej: central topic must be centered) and children position. // Update the figure position(ej: central topic must be centered) and children position.
this._updatePositionOnChangeSize(oldSize, size); this._updatePositionOnChangeSize(oldSize, size, updatePosition);
mindplot.EventBus.instance.fireEvent(mindplot.EventBus.events.NodeResizeEvent,[this]); mindplot.EventBus.instance.fireEvent(mindplot.EventBus.events.NodeResizeEvent,[this]);
} }
}; };
mindplot.Topic.prototype._updatePositionOnChangeSize = function(oldSize, newSize) { mindplot.Topic.prototype._updatePositionOnChangeSize = function(oldSize, newSize, updatePosition) {
core.assert(false, "this method must be overided"); core.assert(false, "this method must be overided");
}; };
@ -1284,7 +1284,7 @@ mindplot.Topic.prototype.createDragNode = function()
return dragNode; return dragNode;
}; };
mindplot.Topic.prototype.updateNode = function() mindplot.Topic.prototype.updateNode = function(updatePosition)
{ {
if(this.isInWorkspace()){ if(this.isInWorkspace()){
var textShape = this.getTextShape(); var textShape = this.getTextShape();
@ -1302,7 +1302,7 @@ mindplot.Topic.prototype.updateNode = function()
} }
var newSize = {width:width,height:height}; var newSize = {width:width,height:height};
this.setSize(newSize); this.setSize(newSize, false, updatePosition);
// Positionate node ... // Positionate node ...
textShape.setPosition(iconOffset+this._offset, pos); textShape.setPosition(iconOffset+this._offset, pos);

View File

@ -257,14 +257,14 @@ mindplot.XMLMindmapSerializer_Pela.prototype.loadFromDom = function(dom)
mindplot.XMLMindmapSerializer_Pela.prototype._deserializeNode = function(domElem, mindmap) mindplot.XMLMindmapSerializer_Pela.prototype._deserializeNode = function(domElem, mindmap)
{ {
var type = (domElem.getAttribute('central') != null) ? mindplot.NodeModel.CENTRAL_TOPIC_TYPE : mindplot.NodeModel.MAIN_TOPIC_TYPE; var type = (domElem.getAttribute('central') != null) ? mindplot.NodeModel.CENTRAL_TOPIC_TYPE : mindplot.NodeModel.MAIN_TOPIC_TYPE;
var topic = mindmap.createNode(type);
// Load attributes... // Load attributes...
var id = domElem.getAttribute('id'); var id = domElem.getAttribute('id');
if(id) { if(id) {
topic.setId(id); id=parseInt(id);
} }
var topic = mindmap.createNode(type, id);
var text = domElem.getAttribute('text'); var text = domElem.getAttribute('text');
if (text) { if (text) {
topic.setText(text); topic.setText(text);
@ -330,6 +330,7 @@ mindplot.XMLMindmapSerializer_Pela.prototype._deserializeNode = function(domElem
if (position) { if (position) {
var pos = position.split(','); var pos = position.split(',');
topic.setPosition(pos[0], pos[1]); topic.setPosition(pos[0], pos[1]);
topic.setFinalPosition(pos[0], pos[1]);
} }
//Creating icons and children nodes //Creating icons and children nodes

View File

@ -41,6 +41,8 @@ mindplot.commands.AddTopicCommand = mindplot.Command.extend(
var doneFn = function(){ var doneFn = function(){
// Finally, focus ... // Finally, focus ...
var designer = commandContext._designer;
designer.onObjectFocusEvent.attempt(topic, designer);
topic.setOnFocus(true); topic.setOnFocus(true);
}; };

View File

@ -0,0 +1,60 @@
/*
* Copyright [2011] [wisemapping]
*
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
* It is basically the Apache License, Version 2.0 (the "License") plus the
* "powered by wisemapping" text requirement on every single page;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the license at
*
* http://www.wisemapping.org/license
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
mindplot.commands.freeMind={};
mindplot.commands.freeMind.DragTopicCommand = mindplot.Command.extend(
{
initialize: function()
{
this._modifiedTopics=null;
this._id = mindplot.Command._nextUUID();
},
execute: function(commandContext)
{
var keys = this._modifiedTopics.keys();
for(var i=0; i<keys.length; i++){
var id = keys[i];
var modTopic = this._modifiedTopics.get(id);
var topic = commandContext.findTopics(parseInt(id))[0];
var position = topic.getPosition();
var pos = modTopic.newPos;
if(position.x != pos.x || position.y != pos.y){
topic.setPosition(pos.clone(), true);
}
}
},
undoExecute: function(commandContext)
{
var keys = this._modifiedTopics.keys();
for(var i=0; i<keys.length; i++){
var id = keys[i];
var modTopic = this._modifiedTopics.get(id);
var topic = commandContext.findTopics(parseInt(id))[0];
var position = topic.getPosition();
var pos = modTopic.originalPos;
if(position.x != pos.x || position.y != pos.y){
topic.setPosition(pos.clone(), true);
}
}
},
setModifiedTopics:function(modifiedTopics){
this._modifiedTopics = modifiedTopics;
}
});

View File

@ -6,7 +6,7 @@ mindplot.layoutManagers.BaseLayoutManager = new Class({
initialize: function(designer, options) { initialize: function(designer, options) {
this.setOptions(options); this.setOptions(options);
this._boards = new Hash(); this._createBoard();
this._designer = designer; this._designer = designer;
mindplot.EventBus.instance.addEvent(mindplot.EventBus.events.NodeResizeEvent,this._nodeResizeEvent.bind(this)); mindplot.EventBus.instance.addEvent(mindplot.EventBus.events.NodeResizeEvent,this._nodeResizeEvent.bind(this));
mindplot.EventBus.instance.addEvent(mindplot.EventBus.events.NodeMoveEvent,this._nodeMoveEvent.bind(this)); mindplot.EventBus.instance.addEvent(mindplot.EventBus.events.NodeMoveEvent,this._nodeMoveEvent.bind(this));
@ -17,26 +17,31 @@ mindplot.layoutManagers.BaseLayoutManager = new Class({
_nodeResizeEvent:function(node){ _nodeResizeEvent:function(node){
}, },
_nodeMoveEvent:function(node){ _nodeMoveEvent:function(node){
//todo: Usar un solo board para todos los nodos. Testear que ande el set margin cuando se mueven los nodos. var modifiedTopics = [];
this.getTopicBoardForTopic(node).updateChildrenPosition(node); this.getTopicBoardForTopic(node).updateChildrenPosition(node, modifiedTopics);
}, },
_nodeDisconnectEvent:function(targetNode, node){ _nodeDisconnectEvent:function(targetNode, node){
this.getTopicBoardForTopic(targetNode).removeTopicFromBoard(node); var modifiedTopics = [];
this.getTopicBoardForTopic(targetNode).removeTopicFromBoard(node,modifiedTopics);
}, },
_nodeConnectEvent:function(targetNode, node){ _nodeConnectEvent:function(targetNode, node){
this.getTopicBoardForTopic(targetNode).addBranch(node); var modifiedTopics = [];
this.getTopicBoardForTopic(targetNode).addBranch(node,modifiedTopics);
}, },
_NodeRepositionateEvent:function(node){ _NodeRepositionateEvent:function(node){
}, },
_createBoard:function(){
this._boards = new Hash();
},
getTopicBoardForTopic:function(node){ getTopicBoardForTopic:function(node){
var id = node.getId() var id = node.getId();
var result = this._boards[id]; var result = this._boards[id];
if(!result){ if(!result){
result = this.addNode(node); result = this._addNode(node);
} }
return result; return result;
}, },
addNode:function(node){ _addNode:function(node){
var board = null; var board = null;
if (this._isCentralTopic(node)) if (this._isCentralTopic(node))
board = this._createCentralTopicBoard(node); board = this._createCentralTopicBoard(node);

View File

@ -5,10 +5,14 @@ mindplot.layoutManagers.FreeMindLayoutManager = mindplot.layoutManagers.BaseLayo
initialize:function(designer, options){ initialize:function(designer, options){
this.parent(designer, options); this.parent(designer, options);
}, },
_nodeConnectEvent:function(targetNode, node){
if(!this._isCentralTopic(node)){
this.parent(targetNode, node);
}
},
registerListenersOnNode : function(topic) registerListenersOnNode : function(topic)
{ {
var id = topic.getId(); var id = topic.getId();
console.log("registering on node: "+id);
// Register node listeners ... // Register node listeners ...
var designer = this.getDesigner(); var designer = this.getDesigner();
topic.addEventListener('onfocus', function(event) topic.addEventListener('onfocus', function(event)
@ -22,11 +26,11 @@ mindplot.layoutManagers.FreeMindLayoutManager = mindplot.layoutManagers.BaseLayo
topic.addEventListener("mousedown",this._mousedownListener.bindWithEvent(this,[topic])); topic.addEventListener("mousedown",this._mousedownListener.bindWithEvent(this,[topic]));
} }
/*// Register editor events ... // Register editor events ...
if (!this._viewMode) if (!this.getDesigner()._viewMode)
{ {
this._editor.listenEventOnNode(topic, 'dblclick', true); this.getDesigner()._editor.listenEventOnNode(topic, 'dblclick', true);
}*/ }
}, },
_mousedownListener:function(event,topic){ _mousedownListener:function(event,topic){
@ -38,7 +42,9 @@ mindplot.layoutManagers.FreeMindLayoutManager = mindplot.layoutManagers.BaseLayo
workSpace.enableWorkspaceEvents(false); workSpace.enableWorkspaceEvents(false);
var id = topic.getId(); var id = topic.getId();
console.log("down on node: "+id); this._command = new mindplot.commands.freeMind.DragTopicCommand();
this._modifiedTopics = new Hash();
var topics = this.getDesigner()._getTopics(); var topics = this.getDesigner()._getTopics();
// Disable all mouse events. // Disable all mouse events.
for (var i = 0; i < topics.length; i++) for (var i = 0; i < topics.length; i++)
@ -53,6 +59,8 @@ mindplot.layoutManagers.FreeMindLayoutManager = mindplot.layoutManagers.BaseLayo
// Set initial position. // Set initial position.
// var mousePos = screen.getWorkspaceMousePosition(event); // var mousePos = screen.getWorkspaceMousePosition(event);
this._isMovingNode=false;
// Register mouse move listener ... // Register mouse move listener ...
this._mouseMoveListenerInstance = this._mouseMoveListener.bindWithEvent(this,[topic]); this._mouseMoveListenerInstance = this._mouseMoveListener.bindWithEvent(this,[topic]);
screen.addEventListener('mousemove', this._mouseMoveListenerInstance); screen.addEventListener('mousemove', this._mouseMoveListenerInstance);
@ -66,22 +74,70 @@ mindplot.layoutManagers.FreeMindLayoutManager = mindplot.layoutManagers.BaseLayo
} }
}, },
_mouseMoveListener:function(event, node){ _mouseMoveListener:function(event, node){
var screen = this._designer.getWorkSpace().getScreenManager(); if(!this._isMovingNode){
var nodePos = node.getPosition(); this._isMovingNode=true;
var pos = screen.getWorkspaceMousePosition(event); var screen = this._designer.getWorkSpace().getScreenManager();
var x = nodePos.x - pos.x; var nodePos = node.getPosition().clone();
var y = nodePos.y - pos.y; var pos = screen.getWorkspaceMousePosition(event);
var delta = new core.Point(x, y); pos.x = Math.round(pos.x);
var board = this.getTopicBoardForTopic(node.getParent()); pos.y = Math.round(pos.y);
board.setNodeMarginTop(node, delta); //If still in same side
//update children position if(Math.sign(nodePos.x)==Math.sign(pos.x) || (Math.sign(nodePos.x)!=Math.sign(pos.x) && !this._isCentralTopic(node.getParent()))){
this._updateNodePos(node, delta); var x = nodePos.x - pos.x;
var y = nodePos.y - pos.y;
var delta = new core.Point(Math.round(x), Math.round(y));
var board = this.getTopicBoardForTopic(node.getParent());
board.updateEntry(node, delta, this._modifiedTopics);
} else {
var parentBoard = this.getTopicBoardForTopic(node.getParent());
var entryObj = parentBoard.findNodeEntryIndex(node);
var entry = entryObj.table[entryObj.index];
//.removeTopicFromBoard(node,this._modifiedTopics);
parentBoard._removeEntry(node, entryObj.table, entryObj.index, this._modifiedTopics);
this._changeChildrenSide(node, pos, this._modifiedTopics);
node.setPosition(pos.clone(), false);
if(this._modifiedTopics.set){
var key = node.getId();
if(this._modifiedTopics.hasKey(key)){
nodePos = this._modifiedTopics.get(key).originalPos;
}
this._modifiedTopics.set(key,{originalPos:nodePos, newPos:pos});
}
entryObj = parentBoard.findNewNodeEntryIndex(entry);
parentBoard._addEntry(entry, entryObj.table, entryObj.index);
parentBoard._updateTable(entryObj.index, entryObj.table, this._modifiedTopics, true);
//this.getTopicBoardForTopic(node.getParent()).addBranch(node,this._modifiedTopics);
}
this._isMovingNode=false;
}
event.preventDefault(); event.preventDefault();
}, },
_changeChildrenSide:function(node, newPos, modifiedTopics){
var children = node._getChildren();
if(children.length>0){
var refPos = node.getPosition();
for( var i = 0 ; i< children.length ; i++){
var child = children[i];
this._changeChildrenSide(child);
var childPos = child.getPosition();
var oldPos=childPos.clone();
childPos.x = newPos.x +(childPos.x - refPos.x)*-1;
childPos.y = newPos.y +(childPos.y - refPos.y);
child.setPosition(childPos, false);
if(modifiedTopics.set){
var key = node.getId();
if(modifiedTopics.hasKey(key)){
childPos = this._modifiedTopics.get(key).originalPos;
}
this._modifiedTopics.set(key,{originalPos:oldPos, newPos:childPos});
}
}
}
},
_mouseUpListener:function(event, node){ _mouseUpListener:function(event, node){
var id = node.getId(); var id = node.getId();
console.log("up on node: "+id);
var screen = this._designer.getWorkSpace().getScreenManager(); var screen = this._designer.getWorkSpace().getScreenManager();
// Remove all the events. // Remove all the events.
screen.removeEventListener('mousemove', this._mouseMoveListenerInstance); screen.removeEventListener('mousemove', this._mouseMoveListenerInstance);
@ -101,19 +157,16 @@ mindplot.layoutManagers.FreeMindLayoutManager = mindplot.layoutManagers.BaseLayo
this._designer.getWorkSpace().enableWorkspaceEvents(true); this._designer.getWorkSpace().enableWorkspaceEvents(true);
this._command.setModifiedTopics(this._modifiedTopics);
var actionRunner = mindplot.DesignerActionRunner.getInstance();
actionRunner.execute(this._command);
this._command=null;
this._modifiedTopics=null;
// var topicId = draggedTopic.getId(); // var topicId = draggedTopic.getId();
// var command = new mindplot.commands.DragTopicCommand(topicId); // var command = new mindplot.commands.DragTopicCommand(topicId);
}, },
_updateNodePos:function(node, delta){
var pos = node.getPosition();
node.setPosition(new core.Point(pos.x-delta.x, pos.y-delta.y));
/*var children = node._getChildren();
for (var i = 0; i < children.length; i++)
{
this._updateNodePos(children[i],delta);
}*/
},
getClassName:function(){ getClassName:function(){
return mindplot.layoutManagers.FreeMindLayoutManager.NAME; return mindplot.layoutManagers.FreeMindLayoutManager.NAME;
}, },
@ -122,6 +175,33 @@ mindplot.layoutManagers.FreeMindLayoutManager = mindplot.layoutManagers.BaseLayo
}, },
_createCentralTopicBoard:function(node){ _createCentralTopicBoard:function(node){
return new mindplot.layoutManagers.boards.freeMindBoards.CentralTopicBoard(node, this); return new mindplot.layoutManagers.boards.freeMindBoards.CentralTopicBoard(node, this);
},
_updateParentBoard:function(node, modifiedTopics){
var parent = node.getParent();
if(!this._isCentralTopic(parent)){
var parentBoard = this.getTopicBoardForTopic(parent.getParent());
var result = parentBoard.findNodeEntryIndex(parent);
var parentEntry = result.table[result.index];
var board = this.getTopicBoardForTopic(parent);
var table = board._getTableForNode(null);
if(table.length>0){
var firstChild = table[0];
var marginTop = parentEntry.getPosition()-(firstChild.getPosition()-firstChild.getTotalMarginTop());
parentBoard.setNodeChildrenMarginTop(parentEntry,marginTop);
var lastChild = table[table.length-1];
var marginBottom = (lastChild.getPosition()+lastChild.getTotalMarginBottom())-parentEntry.getPosition();
parentBoard.setNodeChildrenMarginBottom(parentEntry,marginBottom);
parentBoard._updateTable(result.index, result.table, modifiedTopics, false);
}
this._updateParentBoard(parent, modifiedTopics);
}
},
_updateChildrenBoards:function(node, delta, modifiedTopics){
var board = this.getTopicBoardForTopic(node);
var topics = board._getTableForNode(null);
for(var i=0; i<topics.length; i++){
board._updateEntryPos(topics[i],delta, modifiedTopics, false);
}
} }
}); });

View File

@ -16,7 +16,7 @@ mindplot.layoutManagers.OriginalLayoutManager = mindplot.layoutManagers.BaseLayo
if(this._isCentralTopic(node)){ if(this._isCentralTopic(node)){
var size = node.getSize(); var size = node.getSize();
if(!this._isCentralTopic(node)) if(!this._isCentralTopic(node))
this.getTopicBoardForTopic(node).updateChildrenPosition(node,size.height/2); this.getTopicBoardForTopic(node).updateChildrenPosition(node,size.height/2, []);
} }
}, },
_NodeRepositionateEvent:function(node){ _NodeRepositionateEvent:function(node){

View File

@ -13,17 +13,17 @@ mindplot.layoutManagers.boards.Board = new Class({
getClassName:function(){ getClassName:function(){
return mindplot.layoutManagers.boards.Board.NAME; return mindplot.layoutManagers.boards.Board.NAME;
}, },
removeTopicFromBoard:function(node){ removeTopicFromBoard:function(node, modifiedTopics){
core.Utils.assert(false, "no Board implementation found!"); core.assert(false, "no Board implementation found!");
}, },
addBranch:function(node){ addBranch:function(node, modifiedTopics){
core.Utils.assert(false, "no Board implementation found!"); core.assert(false, "no Board implementation found!");
}, },
updateChildrenPosition:function(node){ updateChildrenPosition:function(node, modifiedTopics){
core.Utils.assert(false, "no Board implementation found!"); core.assert(false, "no Board implementation found!");
}, },
setNodeMarginTop:function(node, delta){ setNodeMarginTop:function(node, delta){
core.Utils.assert(false, "no Board implementation found!"); core.assert(false, "no Board implementation found!");
} }
}); });

View File

@ -9,57 +9,109 @@ mindplot.layoutManagers.boards.freeMindBoards.Board = mindplot.layoutManagers.bo
this._positionTables = this._createTables(); this._positionTables = this._createTables();
}, },
_createTables:function(){ _createTables:function(){
core.Utils.assert(false, "no Board implementation found!") core.assert(false, "no Board implementation found!")
}, },
_getTableForNode:function(node){ _getTableForNode:function(node){
core.Utils.assert(false, "no Board implementation found!") core.assert(false, "no Board implementation found!")
}, },
removeTopicFromBoard:function(node){ removeTopicFromBoard:function(node, modifiedTopics){
var table = this._getTableForNode(node); var table = this._getTableForNode(node);
var position = node.getPosition(); var id = node.getId();
var y = position.y;
//search for position //search for position
for(var i = 0; i< table.length ; i++){ var i;
for(i = 0; i< table.length ; i++){
var entry = table[i]; var entry = table[i];
if (entry.position == y){ if (entry.getId() == id){
this._removeEntry(node, table, i);
break; break;
} }
} }
core.assert(i<table.length,"node not found. Could not remove");
this._removeEntry(node, table, i, modifiedTopics);
this._updateTable(0,table, modifiedTopics, true);
}, },
addBranch:function(node){ addBranch:function(node,modifiedTopics){
var result = this.findNodeEntryIndex(node); var pos = (this._layoutManager._isMovingNode?node.getPosition():node.getModel().getFinalPosition() || node.getPosition());
this._insertNewEntry(node, result.table, result.index); var entry = new mindplot.layoutManagers.boards.freeMindBoards.Entry(node, !this._layoutManager._isMovingNode);
var result = this.findNewNodeEntryIndex(entry);
// if creating a sibling or child
if(!this._layoutManager._isMovingNode && this._layoutManager.getDesigner().getSelectedNodes().length>0){
var selectedNode = this._layoutManager.getDesigner().getSelectedNodes()[0];
if(selectedNode.getParent()!= null && node.getParent().getId() == selectedNode.getParent().getId() && !this._layoutManager._isCentralTopic(node.getParent())){
//creating a sibling - Lets put the new node below the selected node.
var parentBoard = this._layoutManager.getTopicBoardForTopic(selectedNode.getParent());
var selectedNodeResult = parentBoard.findNodeEntryIndex(selectedNode);
var selectedNodeEntry = selectedNodeResult.table[selectedNodeResult.index];
entry.setPosition(null, selectedNodeEntry.getPosition()+selectedNodeEntry.getTotalMarginBottom() + entry.getMarginTop());
result.index = selectedNodeResult.index+1;
} else if(node.getParent().getId() == selectedNode.getId()){
//creating a child node - Lest put the new node as the last child.
var selectedNodeBoard = this._layoutManager.getTopicBoardForTopic(selectedNode);
var table = selectedNodeBoard._getTableForNode(node);
if(table.length>0){
//if no children use the position set by Entry initializer. Otherwise place as last child
var lastChild = table[table.length-1];
entry.setPosition(null, lastChild.getPosition()+lastChild.getTotalMarginBottom() + entry.getMarginTop());
}
result.index = table.length;
}
}
this._addEntry(entry, result.table, result.index);
if(pos){
if(result.index>0){
var prevEntry =result.table[result.index-1];
entry.setMarginTop(pos.y-(prevEntry.getPosition() + prevEntry.getTotalMarginBottom()));
}
else if(result.table.length>1){
var nextEntry = result.table[1];
nextEntry.setMarginTop((nextEntry.getPosition() - nextEntry.getTotalMarginTop())-pos.y);
}
var parent = node.getParent();
if(!this._layoutManager._isCentralTopic(parent) && (result.index == 0 || result.index==result.table.length-1)){
var board = this._layoutManager.getTopicBoardForTopic(parent.getParent());
var res2 = board.findNodeEntryIndex(parent);
var parentEntry = res2.table[res2.index];
var totalMarginTop = parentEntry.getTotalMarginTop();
var totalMarginBottom = parentEntry.getTotalMarginBottom();
var parentPosition = parentEntry.getPosition();
if(result.index==0 && pos.y < parentPosition){
var childrenMarginTop = parentEntry.getPosition()-(pos.y-entry.getTotalMarginTop());
parentEntry.setMarginTop(totalMarginTop-childrenMarginTop);
}else if(result.index==result.table.length-1 && pos.y>parentPosition){
var childrenMarginBottom = (pos.y+entry.getTotalMarginBottom())-parentEntry.getPosition();
parentEntry.setMarginBottom(totalMarginBottom - childrenMarginBottom);
}
}
}
this._updateTable(result.index, result.table,modifiedTopics, false);
this._layoutManager._updateParentBoard(node, modifiedTopics);
}, },
_insertNewEntry:function(node, table, index){ _removeEntry:function(node, table, index, modifiedTopics){
var entry = new mindplot.layoutManagers.boards.freeMindBoards.Entry(node);
table.splice(index, 0, entry);
this._updateTable(index, table);
},
_removeEntry:function(node, table, index){
table.splice(index, 1); table.splice(index, 1);
this._updateTable(index, table); this._updateTable(index, table, modifiedTopics, false);
}, },
_updateTable:function(index, table){ _addEntry:function(entry, table, index){
table.splice(index, 0, entry);
},
_updateTable:function(index, table, modifiedTopics, updateParents){
var i = index; var i = index;
if(index >= table.length){ if(index >= table.length){
i = table.length -1; i = table.length -1;
} }
var modifiedTopics = [];
var delta = null; var delta = null;
//check from index to 0; //check from index to 0;
if(i>0){ if(i>0){
var entry = table[i]; var entry = table[i];
var prevEntry = table[i-1]; var prevEntry = table[i-1];
var marginTop = entry.getPosition() + entry.getMarginTop();
var marginBottom = prevEntry.getPosition() - prevEntry.getMarginBottom(); var margin = entry.getTotalMarginTop() + prevEntry.getTotalMarginBottom();
if(marginTop>marginBottom){ var distance = Math.abs(prevEntry.getPosition() - entry.getPosition());
delta = marginBottom - marginTop; if(distance!=margin){
delta = (distance - margin)*Math.sign(prevEntry.getPosition() - entry.getPosition());
i--; i--;
while(i >= 0){ while(i >= 0){
this._moveTopic(table[i], delta, modifiedTopics); this._updateEntryPos(table[i], new core.Point(null, delta), modifiedTopics, updateParents);
i--; i--;
} }
} }
@ -72,27 +124,25 @@ mindplot.layoutManagers.boards.freeMindBoards.Board = mindplot.layoutManagers.bo
if( i<table.length-1){ if( i<table.length-1){
entry = table[i]; entry = table[i];
var nextEntry = table[i+1]; var nextEntry = table[i+1];
marginBottom = entry.getPosition() - entry.getMarginBottom(); var margin = entry.getTotalMarginBottom() + nextEntry.getTotalMarginTop();
marginTop = nextEntry.getPosition() + nextEntry.getMarginTop(); var distance = Math.abs(entry.getPosition() - nextEntry.getPosition());
if(marginTop>marginBottom){ if(distance!=margin){
delta = marginTop-marginBottom; delta = (distance - margin)*Math.sign(nextEntry.getPosition() - entry.getPosition());
i++; i++;
while(i<table.length){ while(i<table.length){
this._moveTopic(table[i], delta, modifiedTopics); this._updateEntryPos(table[i], new core.Point(null, delta), modifiedTopics, updateParents);
i++; i++;
} }
} }
} }
// if(updateParents && (i==0 || i==table.length-1)){
// this._layoutManager._updateParentBoard(table[i].getNode(), modifiedTopics);
// }
}, },
_moveTopic:function(entry, delta, modifiedTopics){ updateChildrenPosition:function(node, modifiedTopics){
var pos = entry.getPosition();
pos -= delta;
entry.setPosition(pos);
modifiedTopics.push(entry);
},
updateChildrenPosition:function(node){
var result = this.findNodeEntryIndex(node); var result = this.findNodeEntryIndex(node);
this._updateTable(result.index, result.table); this._updateTable(result.index, result.table, modifiedTopics, false);
}, },
findNodeEntryIndex:function(node){ findNodeEntryIndex:function(node){
var table = this._getTableForNode(node); var table = this._getTableForNode(node);
@ -103,16 +153,65 @@ mindplot.layoutManagers.boards.freeMindBoards.Board = mindplot.layoutManagers.bo
var i; var i;
for(i = 0; i< table.length ; i++){ for(i = 0; i< table.length ; i++){
var entry = table[i]; var entry = table[i];
if (entry.getPosition() < y){ if (entry.getNode().getId() == node.getId()){
break; break;
} }
} }
return {index:i, table:table}; return {index:i, table:table};
}, },
setNodeMarginTop:function(node, delta){ findNewNodeEntryIndex:function(entry){
var result = this.findNodeEntryIndex(node); var table = this._getTableForNode(entry.getNode());
var entry = result.table[result.index]; var position = entry.getPosition();
//search for position
var i;
for(i = 0; i< table.length ; i++){
var tableEntry = table[i];
if (tableEntry.getPosition() > position){
break;
}
}
return {index:i, table:table};
},
setNodeMarginTop:function(entry, delta){
var marginTop = entry.getMarginTop()-delta.y; var marginTop = entry.getMarginTop()-delta.y;
entry.setMarginTop(marginTop); entry.setMarginTop(marginTop);
},
setNodeMarginBottom:function(entry, delta){
var marginBottom = entry.getMarginBottom()-delta.y;
entry.setMarginBottom(marginBottom);
},
setNodeChildrenMarginTop:function(entry, delta){
var marginTop = entry.getChildrenMarginTop()-delta.y;
entry.setChildrenMarginTop(delta);
},
setNodeChildrenMarginBottom:function(entry, delta){
var marginBottom = entry.getChildrenMarginBottom()-delta.y;
entry.setChildrenMarginBottom(delta);
},
updateEntry:function(node, delta, modifiedTopics){
var result = this.findNodeEntryIndex(node);
if(result.index < result.table.length){
var entry = result.table[result.index];
if(result.index!=0)
this.setNodeMarginTop(entry, delta);
this._updateEntryPos(entry, delta, modifiedTopics, false);
this._updateTable(result.index, result.table, modifiedTopics, false);
this._layoutManager._updateParentBoard(entry.getNode(), modifiedTopics);
}
},
_updateEntryPos:function(entry, delta, modifiedTopics, updateParents){
var pos = entry.getNode().getPosition().clone();
var newPos = new core.Point(pos.x-(delta.x==null?0:delta.x), pos.y-delta.y);
entry.setPosition(newPos.x, newPos.y);
this._layoutManager._updateChildrenBoards(entry.getNode(), delta, modifiedTopics);
// if(updateParents)
// this._layoutManager._updateParentBoard(entry.getNode(), modifiedTopics);
if(modifiedTopics.set){
var key = entry.getId();
if(modifiedTopics.hasKey(key)){
pos = modifiedTopics.get(key).originalPos;
}
modifiedTopics.set(key,{originalPos:pos, newPos:newPos});
}
} }
}); });

View File

@ -1,43 +1,91 @@
mindplot.layoutManagers.boards.freeMindBoards.Entry = new Class({ mindplot.layoutManagers.boards.freeMindBoards.Entry = new Class({
initialize:function(node){ initialize:function(node, useFinalPosition){
this._node = node; this._node = node;
this._DEFAULT_X_GAP = 30; this._DEFAULT_X_GAP = 30;
var pos = node.getPosition(); var pos = node.getModel().getFinalPosition();
if(!pos){ if(useFinalPosition && pos){
var parent = node.getParent(); this.setPosition(pos.x, pos.y);
pos = parent.getPosition().clone(); }
var pwidth = parent.getSize().width; else{
var width = node.getSize().width; pos = node.getPosition();
pos.x = pos.x + Math.sign(pos.x) * (this._DEFAULT_X_GAP + pwidth/2 + width/2); if(!pos){
node.setPosition(pos, false); var parent = node.getParent();
pos = parent.getPosition().clone();
var pwidth = parent.getSize().width;
var width = node.getSize().width;
pos.x = pos.x + Math.sign(pos.x) * (this._DEFAULT_X_GAP + pwidth/2 + width/2);
node.setPosition(pos, false);
}
} }
this._position = pos.y; this._position = pos.y;
var height = node.getSize().height;
this._DEFAULT_GAP = 10; this._DEFAULT_GAP = 10;
this._marginTop = this._DEFAULT_GAP + height/2; var height = this.getNode().getSize().height;
this._marginBottom = this._DEFAULT_GAP + height/2; this._minimalMargin = this._DEFAULT_GAP + height/2;
this._marginTop = this._minimalMargin;
this._marginBottom = this._minimalMargin;
this._marginTopChildren=0;
this._marginBottomChildren=0;
}, },
getNode:function(){ getNode:function(){
return this._node; return this._node;
}, },
getId:function(){
return this.getNode().getId();
},
getPosition:function(){ getPosition:function(){
return this._position; return this._position;
}, },
setPosition:function(pos){ setPosition:function(x,y){
var position = this._node.getPosition(); var position = this._node.getPosition().clone();
position.y = pos; position.y = y;
this._node.setPosition(position); if(null != x){
this._position = pos; position.x = x;
}
this._node.setPosition(position, false);
this._position = y;
}, },
getMarginTop:function(){ getMarginTop:function(){
return this._marginTop; return this._marginTop;
}, },
setMarginTop:function(value){ setMarginTop:function(value){
if(value >= this._DEFAULT_GAP){ if(value >= this._minimalMargin){
this._marginTop = value; this._marginTop = value;
} }
}, },
setMarginBottom:function(value){
if(value >= this._minimalMargin){
this._marginBottom = value;
}
},
getMarginBottom:function(){ getMarginBottom:function(){
return this._marginTop; return this._marginBottom;
},
getChildrenMarginTop:function(){
return this._marginTopChildren;
},
setChildrenMarginTop:function(value){
if(value >= this._minimalMargin){
this._marginTopChildren = value - this._minimalMargin;
}else{
this._marginTopChildren=0;
}
},
setChildrenMarginBottom:function(value){
if(value >= this._minimalMargin){
this._marginBottomChildren = value - this._minimalMargin;
}else{
this._marginBottomChildren=0;
}
},
getChildrenMarginBottom:function(){
return this._marginBottomChildren;
},
getTotalMarginTop:function(){
return this._marginTopChildren+this._marginTop;
},
getTotalMarginBottom:function(){
return this._marginBottomChildren + this._marginBottom;
} }
}); });

View File

@ -64,11 +64,11 @@ public class ExportController extends BaseMultiActionController {
final String mapIdStr = request.getParameter(MAP_ID_PARAMETER); final String mapIdStr = request.getParameter(MAP_ID_PARAMETER);
if (mapIdStr != null) { if (mapIdStr != null) {
final String mapSvg = request.getParameter(MAP_SVG_PARAMETER);
try { try {
int mindmapId = Integer.parseInt(mapIdStr); int mindmapId = Integer.parseInt(mapIdStr);
final String mapSvg = request.getParameter(MAP_SVG_PARAMETER);
logger.debug("SVG Map to export:"+mapSvg); logger.debug("SVG Map to export:"+mapSvg);
if(mapSvg==null || mapSvg.isEmpty()) if(mapSvg==null || mapSvg.isEmpty())
{ {
@ -116,6 +116,7 @@ public class ExportController extends BaseMultiActionController {
} catch (Throwable e) { } catch (Throwable e) {
logger.error("Unexpexted error during export process", e); logger.error("Unexpexted error during export process", e);
response.setStatus(HttpServletResponse.SC_NOT_FOUND); response.setStatus(HttpServletResponse.SC_NOT_FOUND);
logger.error("map: "+mapSvg);
} }
} else { } else {
logger.warn("mapIdStr is null.Image could not be imported. UserAgent:" + request.getHeaders(UserAgent.USER_AGENT_HEADER)); logger.warn("mapIdStr is null.Image could not be imported. UserAgent:" + request.getHeaders(UserAgent.USER_AGENT_HEADER));