Merged in christinaKorger/wisemapping-open-source (pull request #2)

add jsdoc to mindplot module
This commit is contained in:
Paulo Gustavo Veiga 2015-03-24 16:22:11 -03:00
commit f7d58787c8
46 changed files with 1524 additions and 108 deletions

View File

@ -16,9 +16,15 @@
* limitations under the License.
*/
mindplot.CentralTopic = new Class({
mindplot.CentralTopic = new Class(/** @lends CentralTopic*/{
Extends:mindplot.Topic,
/**
* @extends mindplot.Topic
* @constructs
* @param model
* @param options
*/
initialize:function (model, options) {
this.parent(model, options);
},
@ -32,15 +38,18 @@ mindplot.CentralTopic = new Class({
});
},
/** */
workoutIncomingConnectionPoint:function () {
return this.getPosition();
},
/** */
setCursor:function (type) {
type = (type == 'move') ? 'default' : type;
this.parent(type);
},
/** */
updateTopicShape:function () {
},
@ -52,10 +61,12 @@ mindplot.CentralTopic = new Class({
this.setPosition(zeroPoint);
},
/** */
getShrinkConnector:function () {
return null;
},
/** */
workoutOutgoingConnectionPoint:function (targetPosition) {
$assert(targetPosition, 'targetPoint can not be null');
var pos = this.getPosition();

View File

@ -16,23 +16,37 @@
* limitations under the License.
*/
mindplot.Command = new Class(
{
mindplot.Command = new Class(/** @lends mindplot.Command */{
/**
* @classdesc The command base class for handling do/undo mindmap operations
* @constructs
*/
initialize: function()
{
this._id = mindplot.Command._nextUUID();
},
/**
* @abstract
*/
execute: function(commandContext)
{
throw "execute must be implemented.";
},
/**
* Triggered by the undo button - reverses the executed command
* @abstract
*/
undoExecute: function(commandContext)
{
throw "undo must be implemented.";
},
/**
* Returns the unique id of this command
* @returns {Number} command id
*/
getId:function()
{
return this._id;

View File

@ -16,8 +16,14 @@
* limitations under the License.
*/
mindplot.Designer = new Class({
mindplot.Designer = new Class(/** @lends Designer */{
Extends: mindplot.Events,
/**
* @constructs
* @param {Object} options
* @param {HTMLElement} divElement
* @extends mindplot.Events
*/
initialize:function (options, divElement) {
$assert(options, "options must be defined");
$assert(options.zoom, "zoom must be defined");
@ -80,6 +86,9 @@ mindplot.Designer = new Class({
this.deselectAll();
},
/**
* @private
*/
_registerWheelEvents:function () {
var workspace = this._workspace;
var me = this;
@ -119,7 +128,11 @@ mindplot.Designer = new Class({
mindplot.DesignerKeyboard.getInstance().activate();
},
/**
* @param {String} type the event type
* @param {Function} listener
* forwards to the TopicEventDispatcher or the parent Events class, depending on the type
*/
addEvent:function (type, listener) {
if (type == mindplot.TopicEvent.EDIT || type == mindplot.TopicEvent.CLICK) {
var editor = mindplot.TopicEventDispatcher.getInstance();
@ -129,6 +142,9 @@ mindplot.Designer = new Class({
}
},
/**
* @private
*/
_registerMouseEvents:function () {
var workspace = this._workspace;
var screenManager = workspace.getScreenManager();
@ -165,47 +181,15 @@ mindplot.Designer = new Class({
function noopHandler(evt) {
evt.stopPropagation();
evt.preventDefault();
}
// Enable drag events ...
// @Todo: Images support on progress ...
// Element.NativeEvents.dragenter = 2;
// Element.NativeEvents.dragexit = 2;
// Element.NativeEvents.dragover = 2;
// Element.NativeEvents.drop = 2;
//
// screenManager.addEvent('dragenter', noopHandler);
// screenManager.addEvent('dragexit', noopHandler);
// screenManager.addEvent('dragover', noopHandler);
// screenManager.addEvent('drop', function (evt) {
// evt.stopPropagation();
// evt.preventDefault();
////
// var files = evt.event.dataTransfer.files;
// console.log(event);
//
// var count = files.length;
//
// // Only call the handler if 1 or more files was dropped.
// if (count > 0) {
//
// var model = this.getMindmap().createNode();
// model.setImageSize(80, 43);
// model.setMetadata("{'media':'video,'url':'http://www.youtube.com/watch?v=P3FrXftyuzw&feature=g-vrec&context=G2b4ab69RVAAAAAAAAAA'}");
// model.setImageUrl("images/logo-small.png");
// model.setShapeType(mindplot.model.TopicShape.IMAGE);
//
// var position = screenManager.getWorkspaceMousePosition(evt);
// model.setPosition(position.x, position.y);
// model.setPosition(100, 100);
//
// this._actionDispatcher.addTopics([model]);
// }
// }.bind(this));
};
},
/**
* @private
* @param {mindplot.Workspace} workspace
* @return {mindplot.DragManager} the new dragManager for the workspace with events
* registered
*/
_buildDragManager:function (workspace) {
var designerModel = this.getModel();
@ -242,13 +226,23 @@ mindplot.Designer = new Class({
return dragManager;
},
/**
* @param {width:Number, height:Number} size
* sets width and height of the workspace
*/
setViewPort:function (size) {
this._workspace.setViewPort(size);
var model = this.getModel();
this._workspace.setZoom(model.getZoom(), true);
},
/**
* @private
* @param {mindplot.model.NodeModel} model
* @param {Boolean} readOnly
* @return {mindplot.CentralTopic|mindplot.MainTopic} the topic to the given model,
* connected, added to the drag manager, with events registered - complying type & read mode
*/
_buildNodeGraph:function (model, readOnly) {
// Create node graph ...
var topic = mindplot.NodeGraph.create(model, {readOnly:readOnly});
@ -311,6 +305,12 @@ mindplot.Designer = new Class({
return topic;
},
/**
* @param {?mindplot.Topic} currentObject
* @param {Event=} event
* sets focus to the given currentObject and removes it from any other objects if not
* triggered with Ctrl pressed
*/
onObjectFocusEvent:function (currentObject, event) {
// Close node editors ..
var topics = this.getModel().getTopics();
@ -331,6 +331,7 @@ mindplot.Designer = new Class({
},
/** sets focus to all model entities, i.e. relationships and topics */
selectAll:function () {
var model = this.getModel();
var objects = model.getEntities();
@ -339,6 +340,7 @@ mindplot.Designer = new Class({
});
},
/** removes focus from all model entities, i.e. relationships and topics */
deselectAll:function () {
var objects = this.getModel().getEntities();
_.each(objects, function (object) {
@ -347,8 +349,8 @@ mindplot.Designer = new Class({
},
/**
* Set the zoom of the map.
* @param: zoom: number between 0.3 and 1.9
* Set the zoom of the map
* @param {Number} zoom number between 0.3 and 1.9
*/
setZoom:function (zoom) {
if (zoom > 1.9 || zoom < 0.3) {
@ -359,6 +361,10 @@ mindplot.Designer = new Class({
this._workspace.setZoom(zoom);
},
/**
* @param {Number=} factor
* zoom out by the given factor, or 1.2, if undefined
*/
zoomOut:function (factor) {
if (!factor)
factor = 1.2;
@ -375,6 +381,10 @@ mindplot.Designer = new Class({
},
/**
* @param {Number=} factor
* zoom in by the given factor, or 1.2, if undefined
*/
zoomIn:function (factor) {
if (!factor)
factor = 1.2;
@ -391,6 +401,7 @@ mindplot.Designer = new Class({
}
},
/** copy selected topics to a private clipboard */
copyToClipboard:function () {
var topics = this.getModel().filterSelectedTopics();
if (topics.length <= 0) {
@ -417,6 +428,7 @@ mindplot.Designer = new Class({
$notify($msg('SELECTION_COPIED_TO_CLIPBOARD'));
},
/** paste clipboard contents to the mindmap */
pasteClipboard:function () {
if (this._clipboard.length == 0) {
$notify($msg('CLIPBOARD_IS_EMPTY'));
@ -426,11 +438,12 @@ mindplot.Designer = new Class({
this._clipboard = [];
},
/** @return {mindplot.DesignerModel} model */
getModel:function () {
return this._model;
},
/** collapse the subtree of the selected topic */
shrinkSelectedBranch:function () {
var nodes = this.getModel().filterSelectedTopics();
if (nodes.length <= 0 || nodes.length != 1) {
@ -446,6 +459,7 @@ mindplot.Designer = new Class({
}
},
/** create a NodeModel for the selected node's child and add it via the ActionDispatcher */
createChildForSelectedNode:function () {
var nodes = this.getModel().filterSelectedTopics();
if (nodes.length <= 0) {
@ -471,6 +485,9 @@ mindplot.Designer = new Class({
},
/**
* @private
*/
_copyNodeProps: function(sourceModel,targetModel){
// I don't copy the font size if the target is the source is the central topic.
@ -518,6 +535,12 @@ mindplot.Designer = new Class({
}
},
/**
* @private
* @param {mindplot.Topic} topic the parent topic of the child to create the NodeModel for
* @param {core.Point} mousePos the mouse position
* @return {mindplot.NodeModel} the node model for the new child
*/
_createChildModel:function (topic, mousePos) {
// Create a new node ...
var parentModel = topic.getModel();
@ -537,6 +560,11 @@ mindplot.Designer = new Class({
return childModel;
},
/**
* @param {Events} event
* @param {mindplot.model.NodeModel} model
* @todo not used
*/
addDraggedNode:function (event, model) {
$assert(event, "event can not be null");
$assert(model, "model can not be null");
@ -551,6 +579,10 @@ mindplot.Designer = new Class({
topic.fireEvent("mousedown", event);
},
/**
* creates a sibling or child node of the selected node, if the selected node is the
* central topic
*/
createSiblingForSelectedNode:function () {
var nodes = this.getModel().filterSelectedTopics();
if (nodes.length <= 0) {
@ -585,6 +617,11 @@ mindplot.Designer = new Class({
}
},
/**
* @private
* @param {mindplot.Topic} topic the topic to create the sibling to
* @return {mindplot.NodeModel} the node model of the sibling
*/
_createSiblingModel:function (topic) {
var result = null;
var parentTopic = topic.getOutgoingConnectedTopic();
@ -606,6 +643,9 @@ mindplot.Designer = new Class({
return result;
},
/**
* @param {Event} event
*/
showRelPivot:function (event) {
var nodes = this.getModel().filterSelectedTopics();
@ -623,10 +663,15 @@ mindplot.Designer = new Class({
this._relPivot.start(nodes[0], pos);
},
/** @return the zoom */
getMindmapProperties:function () {
return {zoom:this.getModel().getZoom()};
},
/**
* @param {mindplot.Mindmap} mindmapModel
* @throws will throw an error if mindmapModel is null or undefined
*/
loadMap:function (mindmapModel) {
$assert(mindmapModel, "mindmapModel can not be null");
this._mindmap = mindmapModel;
@ -670,23 +715,33 @@ mindplot.Designer = new Class({
this.fireEvent('loadSuccess');
},
/** */
getMindmap:function () {
return this._mindmap;
},
/** */
undo:function () {
// @Todo: This is a hack...
this._actionDispatcher._actionRunner.undo();
},
/** */
redo:function () {
this._actionDispatcher._actionRunner.redo();
},
/** */
isReadOnly:function () {
return this._options.readOnly;
},
/**
* @private
* @param {mindplot.model.NodeModel} nodeModel
* @return {mindplot.Topic} the topic (extends mindplot.NodeGraph) created to the model
* @todo marked private but called from mindplot.StandaloneActionDispatcher
*/
_nodeModelToNodeGraph:function (nodeModel) {
$assert(nodeModel, "Node model can not be null");
var children = nodeModel.getChildren().slice();
@ -707,6 +762,12 @@ mindplot.Designer = new Class({
return nodeGraph;
},
/**
* @private
* @param {mindplot.model.RelationshipModel} model
* @return {mindplot.Relationship} the relationship created to the model
* @throws will throw an error if model is null or undefined
*/
_relationshipModelToRelationship:function (model) {
$assert(model, "Node model can not be null");
@ -724,12 +785,24 @@ mindplot.Designer = new Class({
return result;
},
/**
* @private
* @param {mindplot.model.RelationshipModel} model
* @return {mindplot.Relationship} the relationship added to the mindmap
* @todo marked private but called from mindplot.StandaloneActionDispatcher
*/
_addRelationship:function (model) {
var mindmap = this.getMindmap();
mindmap.addRelationship(model);
return this._relationshipModelToRelationship(model);
},
/**
* deletes the relationship from the linked topics, DesignerModel, Workspace and Mindmap
* @private
* @param {mindplot.Relationship} rel the relationship to delete
* @todo marked private but called from mindplot.StandaloneActionDispatcher
*/
_deleteRelationship:function (rel) {
var sourceTopic = rel.getSourceTopic();
sourceTopic.deleteRelationship(rel);
@ -744,6 +817,12 @@ mindplot.Designer = new Class({
mindmap.deleteRelationship(rel.getModel());
},
/**
* @private
* @param {mindplot.model.RelationshipModel} model
* @return {mindplot.Relationship} the new relationship with events registered
* @throws will throw an error if the target topic cannot be found
*/
_buildRelationshipShape:function (model) {
var dmodel = this.getModel();
@ -781,10 +860,15 @@ mindplot.Designer = new Class({
// Append it to the workspace ...
dmodel.addRelationship(result);
return result;
},
/**
* @private
* @param {mindplot.model.Topic} node the topic to remove
* removes the given topic and its children from Workspace, DesignerModel and NodeModel
* @todo marked private but called from mindplot.StandaloneActionDispatcher
*/
_removeTopic:function (node) {
if (!node.isCentralTopic()) {
var parent = node._parent;
@ -808,6 +892,9 @@ mindplot.Designer = new Class({
}
},
/**
* @private
*/
_resetEdition:function () {
var screenManager = this._workspace.getScreenManager();
screenManager.fireEvent("update");
@ -815,6 +902,7 @@ mindplot.Designer = new Class({
this._relPivot.dispose();
},
/** */
deleteSelectedEntities:function () {
// Is there some action in progress ?.
this._resetEdition();
@ -849,6 +937,7 @@ mindplot.Designer = new Class({
},
/** */
changeFontFamily:function (font) {
var topicsIds = this.getModel().filterTopicsIds();
if (topicsIds.length > 0) {
@ -857,6 +946,7 @@ mindplot.Designer = new Class({
}
},
/** */
changeFontStyle:function () {
var topicsIds = this.getModel().filterTopicsIds();
if (topicsIds.length > 0) {
@ -864,6 +954,7 @@ mindplot.Designer = new Class({
}
},
/** */
changeFontColor:function (color) {
$assert(color, "color can not be null");
@ -873,6 +964,7 @@ mindplot.Designer = new Class({
}
},
/** */
changeBackgroundColor:function (color) {
var validateFunc = function (topic) {
@ -886,6 +978,7 @@ mindplot.Designer = new Class({
}
},
/** */
changeBorderColor:function (color) {
var validateFunc = function (topic) {
return topic.getShapeType() != mindplot.model.TopicShape.LINE;
@ -897,6 +990,7 @@ mindplot.Designer = new Class({
}
},
/** */
changeFontSize:function (size) {
var topicsIds = this.getModel().filterTopicsIds();
if (topicsIds.length > 0) {
@ -904,6 +998,7 @@ mindplot.Designer = new Class({
}
},
/** */
changeTopicShape:function (shape) {
var validateFunc = function (topic) {
return !(topic.getType() == mindplot.model.INodeModel.CENTRAL_TOPIC_TYPE && shape == mindplot.model.TopicShape.LINE)
@ -916,6 +1011,7 @@ mindplot.Designer = new Class({
}
},
/** */
changeFontWeight:function () {
var topicsIds = this.getModel().filterTopicsIds();
if (topicsIds.length > 0) {
@ -923,6 +1019,7 @@ mindplot.Designer = new Class({
}
},
/** */
addIconType:function (iconType) {
var topicsIds = this.getModel().filterTopicsIds();
if (topicsIds.length > 0) {
@ -930,6 +1027,10 @@ mindplot.Designer = new Class({
}
},
/**
* lets the selected topic open the link editor where the user can define or modify an
* existing link
*/
addLink:function () {
var model = this.getModel();
var topic = model.selectedTopic();
@ -938,6 +1039,7 @@ mindplot.Designer = new Class({
}
},
/** */
addNote:function () {
var model = this.getModel();
var topic = model.selectedTopic();
@ -946,11 +1048,16 @@ mindplot.Designer = new Class({
}
},
/**
* @param {mindplot.Topic} node
* sets the focus to the given node
*/
goToNode:function (node) {
node.setOnFocus(true);
this.onObjectFocusEvent(node);
},
/** @return {mindplot.Workspace} */
getWorkSpace:function () {
return this._workspace;
}

View File

@ -16,35 +16,51 @@
* limitations under the License.
*/
mindplot.DesignerModel = new Class({
mindplot.DesignerModel = new Class(/** @lends DesignerModel */{
Implements:[mindplot.Events],
/**
* @implements {mindplot.Events}
* @constructs
* @param {{readOnly: Boolean, zoom: Number, saveOnLoad: Boolean, size: {width: Number,
* height: Number}, viewPort: {width: Number, height: Number}, container: String,
* persistenceManager: String, mapId: String, locale: String}} options
* options loaded from json config
* @see {@link ConfigParameters.md}
* @see {@link editor.html}
*/
initialize:function (options) {
this._zoom = options.zoom;
this._topics = [];
this._relationships = [];
},
/** @return {Number} zoom between 0.3 (largest text) and 1.9 */
getZoom:function () {
return this._zoom;
},
/** @param {Number} zoom number between 0.3 and 1.9 to set the zoom to */
setZoom:function (zoom) {
this._zoom = zoom;
},
/** @return {@link mindplot.Topic[]} all topics */
getTopics:function () {
return this._topics;
},
/** @return {mindplot.Relationship[]} all relationships */
getRelationships:function () {
return this._relationships;
},
/** @return {mindplot.CentralTopic} the central topic */
getCentralTopic:function () {
var topics = this.getTopics();
return topics[0];
},
/** @return {mindplot.Topic[]} selected topics */
filterSelectedTopics:function () {
var result = [];
for (var i = 0; i < this._topics.length; i++) {
@ -55,6 +71,9 @@ mindplot.DesignerModel = new Class({
return result;
},
/**
* @return {mindplot.Relationship[]} selected relationships
*/
filterSelectedRelationships:function () {
var result = [];
for (var i = 0; i < this._relationships.length; i++) {
@ -65,33 +84,60 @@ mindplot.DesignerModel = new Class({
return result;
},
/**
* @return {Array.<mindplot.Relationship, mindplot.Topic>} all topics and relationships
*/
getEntities:function () {
var result = [].append(this._topics);
result.append(this._relationships);
return result;
},
/**
* removes occurrences of the given topic from the topic array
* @param {mindplot.Topic} topic the topic to remove
*/
removeTopic:function (topic) {
$assert(topic, "topic can not be null");
this._topics.erase(topic);
},
/**
* removes occurrences of the given relationship from the relationship array
* @param {mindplot.Relationship} rel the relationship to remove
*/
removeRelationship:function (rel) {
$assert(rel, "rel can not be null");
this._relationships.erase(rel);
},
/**
* adds the given topic to the topic array
* @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 the topic's id is not a number
*/
addTopic:function (topic) {
$assert(topic, "topic can not be null");
$assert(typeof topic.getId() == "number", "id is not a number:" + topic.getId());
this._topics.push(topic);
},
/**
* adds the given relationship to the relationship array
* @param {mindplot.Relationship} rel the relationship to add
* @throws will throw an error if rel is null or undefined
*/
addRelationship:function (rel) {
$assert(rel, "rel can not be null");
this._relationships.push(rel);
},
/**
* @param {Function=} validate a function to validate nodes
* @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
*/
filterTopicsIds:function (validate, errorMsg) {
var result = [];
var topics = this.filterSelectedTopics();
@ -114,12 +160,19 @@ mindplot.DesignerModel = new Class({
return result;
},
/**
* @return {mindplot.Topic} the first selected topic if one or more are found by the
* filterSelectedTopics function, null otherwise
*/
selectedTopic:function () {
var topics = this.filterSelectedTopics();
return (topics.length > 0) ? topics[0] : null;
},
/**
* @param {String} id the id of the topic to be retrieved
* @return {mindplot.Topic} the topic with the respective id
*/
findTopicById:function (id) {
var result = null;
for (var i = 0; i < this._topics.length; i++) {

View File

@ -16,7 +16,14 @@
* limitations under the License.
*/
mindplot.IconGroup = new Class({
mindplot.IconGroup = new Class(/**@lends IconGroup */{
/**
* @constructs
* @param topicId
* @param iconSize
* @throws will throw an error if topicId is null or undefined
* @throws will throw an error if iconSize is null or undefined
*/
initialize:function (topicId, iconSize) {
$assert($defined(topicId), "topicId can not be null");
$assert($defined(iconSize), "iconSize can not be null");
@ -30,27 +37,37 @@ mindplot.IconGroup = new Class({
},
/** */
setPosition:function (x, y) {
this._group.setPosition(x, y);
},
/** */
getPosition:function () {
return this._group.getPosition();
},
/** */
getNativeElement:function () {
return this._group;
},
/** */
getSize:function () {
return this._group.getSize();
},
/** */
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 {Boolean} remove
* @throws will throw an error if icon is not defined
*/
addIcon:function (icon, remove) {
$defined(icon, "icon is not defined");
@ -86,6 +103,7 @@ mindplot.IconGroup = new Class({
return result;
},
/** */
removeIconByModel:function (featureModel) {
$assert(featureModel, "featureModel can not be null");
@ -108,6 +126,7 @@ mindplot.IconGroup = new Class({
});
},
/** */
moveToFront:function () {
this._group.moveToFront();
},
@ -138,15 +157,31 @@ mindplot.IconGroup = new Class({
icon.getImage().setPosition(iconSize * order + mindplot.IconGroup.ICON_PADDING, mindplot.IconGroup.ICON_PADDING);
}
});
/**
* @constant
* @type {Number}
* @default
*/
mindplot.IconGroup.ICON_PADDING = 5;
mindplot.IconGroup.RemoveTip = new Class({
mindplot.IconGroup.RemoveTip = new Class(/** @lends IconGroup.RemoveTip */{
/**
* @classdesc inner class of IconGroup
* @constructs
* @param container
*/
initialize:function (container) {
$assert(container, "group can not be null");
this._fadeElem = container;
},
/**
* @param topicId
* @param icon
* @throws will throw an error if icon is null or undefined
*/
show:function (topicId, icon) {
$assert(icon, 'icon can not be null');
@ -188,10 +223,14 @@ mindplot.IconGroup.RemoveTip = new Class({
}
},
/** */
hide:function () {
this.close(200);
},
/**
* @param delay
*/
close:function (delay) {
// This is not ok, trying to close the same dialog twice ?
@ -271,6 +310,10 @@ mindplot.IconGroup.RemoveTip = new Class({
return result;
},
/**
* @param topicId
* @param icon
*/
decorate:function (topicId, icon) {
var me = this;

View File

@ -16,8 +16,14 @@
* limitations under the License.
*/
mindplot.MainTopic = new Class({
mindplot.MainTopic = new Class(/** @lends MainTopic */{
Extends:mindplot.Topic,
/**
* @extends mindplot.Topic
* @constructs
* @param model
* @param options
*/
initialize:function (model, options) {
this.parent(model, options);
},
@ -55,6 +61,7 @@ mindplot.MainTopic = new Class({
return group;
},
/** */
updateTopicShape:function (targetTopic, workspace) {
// Change figure based on the connected topic ...
var model = this.getModel();
@ -68,6 +75,7 @@ mindplot.MainTopic = new Class({
}
},
/** */
disconnect:function (workspace) {
this.parent(workspace);
var size = this.getSize();
@ -97,10 +105,12 @@ mindplot.MainTopic = new Class({
}
},
/** */
workoutIncomingConnectionPoint:function (sourcePosition) {
return mindplot.util.Shape.workoutIncomingConnectionPoint(this, sourcePosition);
},
/** */
workoutOutgoingConnectionPoint:function (targetPosition) {
$assert(targetPosition, 'targetPoint can not be null');
var pos = this.getPosition();

View File

@ -16,7 +16,13 @@
* limitations under the License.
*/
mindplot.NodeGraph = new Class({
mindplot.NodeGraph = new Class(/** @lends NodeGraph */{
/**
* @constructs
* @param {mindplot.model.NodeModel} nodeModel
* @param {Object<Number, String, Boolean>} options
* @throws will throw an error if nodeModel is null or undefined
*/
initialize:function(nodeModel, options) {
$assert(nodeModel, "model can not be null");
@ -27,15 +33,21 @@ mindplot.NodeGraph = new Class({
this._size = {width:50,height:20};
},
/** @return true if option is set to read-only */
isReadOnly : function(){
return this._options.readOnly;
},
/** @return model type */
getType : function() {
var model = this.getModel();
return model.getType();
},
/**
* @param {String} id
* @throws will throw an error if the topic id is not a number
*/
setId : function(id) {
$assert(typeof topic.getId() == "number", "id is not a number:" + id);
this.getModel().setId(id);
@ -45,61 +57,82 @@ mindplot.NodeGraph = new Class({
this._elem2d = elem2d;
},
/**
* @return 2D element
* @throws will throw an error if the element is null or undefined within node graph
*/
get2DElement : function() {
$assert(this._elem2d, 'NodeGraph has not been initialized properly');
return this._elem2d;
},
/** @abstract */
setPosition : function(point, fireEvent) {
throw "Unsupported operation";
},
/** */
addEvent : function(type, listener) {
var elem = this.get2DElement();
elem.addEvent(type, listener);
},
/** */
removeEvent : function(type, listener) {
var elem = this.get2DElement();
elem.removeEvent(type, listener);
},
/** */
fireEvent: function(type, event) {
var elem = this.get2DElement();
elem.trigger(type, event);
},
/** */
setMouseEventsEnabled : function(isEnabled) {
this._mouseEvents = isEnabled;
},
/** */
isMouseEventsEnabled : function() {
return this._mouseEvents;
},
/** @return {Object<Number>} size*/
getSize : function() {
return this._size;
},
/** @param {Object<Number>} size*/
setSize : function(size) {
this._size.width = parseInt(size.width);
this._size.height = parseInt(size.height);
},
/**
* @return {mindplot.model.NodeModel} the node model
*/
getModel:function() {
$assert(this._model, 'Model has not been initialized yet');
return this._model;
},
/**
* @param {mindplot.NodeModel} model the node model
* @throws will throw an error if model is null or undefined
*/
setModel : function(model) {
$assert(model, 'Model can not be null');
this._model = model;
},
/** */
getId : function() {
return this._model.getId();
},
/** */
setOnFocus : function(focus) {
if (this._onFocus != focus) {
@ -124,15 +157,18 @@ mindplot.NodeGraph = new Class({
}
},
/** @return {Boolean} true if the node graph is on focus */
isOnFocus : function() {
return this._onFocus;
},
/** */
dispose : function(workspace) {
this.setOnFocus(false);
workspace.removeChild(this);
},
/** */
createDragNode : function(layoutManager) {
var dragShape = this._buildDragShape();
return new mindplot.DragTopic(dragShape, this, layoutManager);
@ -142,12 +178,24 @@ mindplot.NodeGraph = new Class({
$assert(false, '_buildDragShape must be implemented by all nodes.');
},
/** */
getPosition : function() {
var model = this.getModel();
return model.getPosition();
}
});
/**
* creates a new topic from the given node model
* @memberof mindplot.Nodegraph
* @param {mindplot.model.NodeModel} nodeModel
* @param {Object} options
* @throws will throw an error if nodeModel is null or undefined
* @throws will throw an error if the nodeModel's type is null or undefined
* @throws will throw an error if the node type cannot be recognized as either central or main
* topic type
* @return {mindplot.CentralTopic|mindplot.MainTopic} the new topic
*/
mindplot.NodeGraph.create = function(nodeModel, options) {
$assert(nodeModel, 'Model can not be null');

View File

@ -16,33 +16,43 @@
* limitations under the License.
*/
mindplot.StandaloneActionDispatcher = new Class({
mindplot.StandaloneActionDispatcher = new Class(/** @lends StandaloneActionDispatcher */{
Extends:mindplot.ActionDispatcher,
/**
* @extends mindplot.ActionDispatcher
* @constructs
* @param {mindplot.CommandContext} commandContext
*/
initialize:function (commandContext) {
this.parent(commandContext);
this._actionRunner = new mindplot.DesignerActionRunner(commandContext, this);
},
/** */
addTopics:function (models, parentTopicsId) {
var command = new mindplot.commands.AddTopicCommand(models, parentTopicsId);
this.execute(command);
},
/** */
addRelationship:function (model) {
var command = new mindplot.commands.AddRelationshipCommand(model);
this.execute(command);
},
/** */
deleteEntities:function (topicsIds, relIds) {
var command = new mindplot.commands.DeleteCommand(topicsIds, relIds);
this.execute(command);
},
/** */
dragTopic:function (topicId, position, order, parentTopic) {
var command = new mindplot.commands.DragTopicCommand(topicId, position, order, parentTopic);
this.execute(command);
},
/** */
moveTopic:function (topicId, position) {
$assert($defined(topicId), "topicsId can not be null");
$assert($defined(position), "position can not be null");
@ -57,11 +67,13 @@ mindplot.StandaloneActionDispatcher = new Class({
this.execute(command);
},
/** */
moveControlPoint:function (ctrlPoint, point) {
var command = new mindplot.commands.MoveControlPointCommand(ctrlPoint, point);
this.execute(command);
},
/** */
changeFontStyleToTopic:function (topicsIds) {
var commandFunc = function (topic) {
@ -75,6 +87,7 @@ mindplot.StandaloneActionDispatcher = new Class({
},
/** */
changeTextToTopic:function (topicsIds, text) {
$assert($defined(topicsIds), "topicsIds can not be null");
@ -89,6 +102,7 @@ mindplot.StandaloneActionDispatcher = new Class({
this.execute(command);
},
/** */
changeFontFamilyToTopic:function (topicIds, fontFamily) {
$assert(topicIds, "topicIds can not be null");
$assert(fontFamily, "fontFamily can not be null");
@ -106,6 +120,7 @@ mindplot.StandaloneActionDispatcher = new Class({
this.execute(command);
},
/** */
changeFontColorToTopic:function (topicsIds, color) {
$assert(topicsIds, "topicIds can not be null");
$assert(color, "color can not be null");
@ -121,6 +136,7 @@ mindplot.StandaloneActionDispatcher = new Class({
this.execute(command);
},
/** */
changeBackgroundColorToTopic:function (topicsIds, color) {
$assert(topicsIds, "topicIds can not be null");
$assert(color, "color can not be null");
@ -136,6 +152,7 @@ mindplot.StandaloneActionDispatcher = new Class({
this.execute(command);
},
/** */
changeBorderColorToTopic:function (topicsIds, color) {
$assert(topicsIds, "topicIds can not be null");
$assert(color, "topicIds can not be null");
@ -151,6 +168,7 @@ mindplot.StandaloneActionDispatcher = new Class({
this.execute(command);
},
/** */
changeFontSizeToTopic:function (topicsIds, size) {
$assert(topicsIds, "topicIds can not be null");
$assert(size, "size can not be null");
@ -167,6 +185,7 @@ mindplot.StandaloneActionDispatcher = new Class({
this.execute(command);
},
/** */
changeShapeTypeToTopic:function (topicsIds, shapeType) {
$assert(topicsIds, "topicsIds can not be null");
$assert(shapeType, "shapeType can not be null");
@ -181,6 +200,7 @@ mindplot.StandaloneActionDispatcher = new Class({
this.execute(command);
},
/** */
changeFontWeightToTopic:function (topicsIds) {
$assert(topicsIds, "topicsIds can not be null");
@ -197,6 +217,7 @@ mindplot.StandaloneActionDispatcher = new Class({
this.execute(command);
},
/** */
shrinkBranch:function (topicsIds, collapse) {
$assert(topicsIds, "topicsIds can not be null");
@ -209,33 +230,42 @@ mindplot.StandaloneActionDispatcher = new Class({
this.execute(command, false);
},
/** */
addFeatureToTopic:function (topicId, featureType, attributes) {
var command = new mindplot.commands.AddFeatureToTopicCommand(topicId, featureType, attributes);
this.execute(command);
},
/** */
changeFeatureToTopic:function (topicId, featureId, attributes) {
var command = new mindplot.commands.ChangeFeatureToTopicCommand(topicId, featureId, attributes);
this.execute(command);
},
/** */
removeFeatureFromTopic:function (topicId, featureId) {
var command = new mindplot.commands.RemoveFeatureFromTopicCommand(topicId, featureId);
this.execute(command);
},
/** */
execute:function (command) {
this._actionRunner.execute(command);
}
});
mindplot.CommandContext = new Class({
mindplot.CommandContext = new Class(/** @lends CommandContext */{
/**
* @constructs
* @param {mindplot.Designer} designer
*/
initialize:function (designer) {
$assert(designer, "designer can not be null");
this._designer = designer;
},
/** */
findTopics:function (topicsIds) {
$assert($defined(topicsIds), "topicsIds can not be null");
if (!(topicsIds instanceof Array)) {
@ -256,42 +286,51 @@ mindplot.CommandContext = new Class({
return result;
},
/** */
deleteTopic:function (topic) {
this._designer._removeTopic(topic);
},
/** */
createTopic:function (model) {
$assert(model, "model can not be null");
return this._designer._nodeModelToNodeGraph(model);
},
/** */
createModel:function () {
var mindmap = this._designer.getMindmap();
return mindmap.createNode(mindplot.NodeModel.MAIN_TOPIC_TYPE);
},
/** */
addTopic:function (topic) {
var mindmap = this._designer.getMindmap();
return mindmap.addBranch(topic.getModel());
},
/** */
connect:function (childTopic, parentTopic) {
childTopic.connectTo(parentTopic, this._designer._workspace);
},
/** */
disconnect:function (topic) {
topic.disconnect(this._designer._workspace);
},
/** */
addRelationship:function (model) {
$assert(model, "model cannot be null");
return this._designer._addRelationship(model);
},
/** */
deleteRelationship:function (relationship) {
this._designer._deleteRelationship(relationship);
},
/** */
findRelationships:function (relIds) {
$assert($defined(relIds), "relId can not be null");
if (!(relIds instanceof Array)) {
@ -304,6 +343,7 @@ mindplot.CommandContext = new Class({
});
},
/** */
moveTopic:function (topic, position) {
$assert(topic, "topic cannot be null");
$assert(position, "position cannot be null");

View File

@ -16,9 +16,14 @@
* limitations under the License.
*/
mindplot.Topic = new Class({
mindplot.Topic = new Class(/** @lends Topic */{
Extends:mindplot.NodeGraph,
/**
* @extends mindplot.NodeGraph
* @constructs
* @param model
* @param options
*/
initialize:function (model, options) {
this.parent(model, options);
this._children = [];
@ -54,10 +59,15 @@ mindplot.Topic = new Class({
});
},
/**
* @param {String} type the topic shape type
* @see {@link mindplot.model.INodeModel}
*/
setShapeType:function (type) {
this._setShapeType(type, true);
},
/** @return {mindplot.Topic} parent topic */
getParent:function () {
return this._parent;
},
@ -103,6 +113,7 @@ mindplot.Topic = new Class({
},
/** @return {String} topic shape type */
getShapeType:function () {
var model = this.getModel();
var result = model.getShapeType();
@ -120,6 +131,7 @@ mindplot.Topic = new Class({
return innerShape;
},
/** @return {web2d.Line|web2d.Rect|web2d.Image} inner shape of the topic */
getInnerShape:function () {
if (!$defined(this._innerShape)) {
// Create inner box.
@ -207,7 +219,7 @@ mindplot.Topic = new Class({
return result;
},
/** @param {String} type the cursor type, either 'pointer', 'default' or 'move' */
setCursor:function (type) {
var innerShape = this.getInnerShape();
innerShape.setCursor(type);
@ -219,6 +231,7 @@ mindplot.Topic = new Class({
textShape.setCursor(type);
},
/** @return outer shape */
getOuterShape:function () {
if (!$defined(this._outerShape)) {
var rect = this._buildShape(mindplot.Topic.OUTER_SHAPE_ATTRIBUTES, mindplot.model.TopicShape.ROUNDED_RECT);
@ -230,6 +243,7 @@ mindplot.Topic = new Class({
return this._outerShape;
},
/** @return text shape */
getTextShape:function () {
if (!$defined(this._text)) {
this._text = this._buildTextShape(false);
@ -242,6 +256,7 @@ mindplot.Topic = new Class({
return this._text;
},
/** @return icon group */
getOrBuildIconGroup:function () {
if (!$defined(this._iconsGroup)) {
this._iconsGroup = this._buildIconGroup();
@ -252,6 +267,7 @@ mindplot.Topic = new Class({
return this._iconsGroup;
},
/** */
getIconGroup:function () {
return this._iconsGroup;
},
@ -274,6 +290,11 @@ mindplot.Topic = new Class({
return result;
},
/**
* assigns the new feature model to the topic's node model and adds the respective icon
* @param {mindplot.model.FeatureModel} featureModel
* @return {mindplot.Icon} the icon corresponding to the feature model
*/
addFeature:function (featureModel) {
var iconGroup = this.getOrBuildIconGroup();
this.closeEditors();
@ -289,11 +310,13 @@ mindplot.Topic = new Class({
return result;
},
/** */
findFeatureById:function (id) {
var model = this.getModel();
return model.findFeatureById(id);
},
/** */
removeFeature:function (featureModel) {
$assert(featureModel, "featureModel could not be null");
@ -309,14 +332,17 @@ mindplot.Topic = new Class({
this._adjustShapes();
},
/** */
addRelationship:function (relationship) {
this._relationships.push(relationship);
},
/** */
deleteRelationship:function (relationship) {
this._relationships.erase(relationship);
},
/** */
getRelationships:function () {
return this._relationships;
},
@ -344,6 +370,7 @@ mindplot.Topic = new Class({
return result;
},
/** */
setFontFamily:function (value, updateModel) {
var textShape = this.getTextShape();
textShape.setFontFamily(value);
@ -354,6 +381,7 @@ mindplot.Topic = new Class({
this._adjustShapes(updateModel);
},
/** */
setFontSize:function (value, updateModel) {
var textShape = this.getTextShape();
@ -367,6 +395,7 @@ mindplot.Topic = new Class({
},
/** */
setFontStyle:function (value, updateModel) {
var textShape = this.getTextShape();
textShape.setStyle(value);
@ -377,6 +406,7 @@ mindplot.Topic = new Class({
this._adjustShapes(updateModel);
},
/** */
setFontWeight:function (value, updateModel) {
var textShape = this.getTextShape();
textShape.setWeight(value);
@ -387,6 +417,7 @@ mindplot.Topic = new Class({
this._adjustShapes();
},
/** */
getFontWeight:function () {
var model = this.getModel();
var result = model.getFontWeight();
@ -397,6 +428,7 @@ mindplot.Topic = new Class({
return result;
},
/** */
getFontFamily:function () {
var model = this.getModel();
var result = model.getFontFamily();
@ -407,6 +439,7 @@ mindplot.Topic = new Class({
return result;
},
/** */
getFontColor:function () {
var model = this.getModel();
var result = model.getFontColor();
@ -417,6 +450,7 @@ mindplot.Topic = new Class({
return result;
},
/** */
getFontStyle:function () {
var model = this.getModel();
var result = model.getFontStyle();
@ -427,6 +461,7 @@ mindplot.Topic = new Class({
return result;
},
/** */
getFontSize:function () {
var model = this.getModel();
var result = model.getFontSize();
@ -437,6 +472,7 @@ mindplot.Topic = new Class({
return result;
},
/** */
setFontColor:function (value, updateModel) {
var textShape = this.getTextShape();
textShape.setColor(value);
@ -456,6 +492,7 @@ mindplot.Topic = new Class({
}
},
/** */
setText:function (text) {
// Avoid empty nodes ...
if (!text || $.trim(text).length == 0) {
@ -466,6 +503,7 @@ mindplot.Topic = new Class({
this._adjustShapes();
},
/** */
getText:function () {
var model = this.getModel();
var result = model.getText();
@ -475,6 +513,7 @@ mindplot.Topic = new Class({
return result;
},
/** */
setBackgroundColor:function (color) {
this._setBackgroundColor(color, true);
},
@ -494,6 +533,7 @@ mindplot.Topic = new Class({
}
},
/** */
getBackgroundColor:function () {
var model = this.getModel();
var result = model.getBackgroundColor();
@ -503,6 +543,7 @@ mindplot.Topic = new Class({
return result;
},
/** */
setBorderColor:function (color) {
this._setBorderColor(color, true);
},
@ -522,6 +563,7 @@ mindplot.Topic = new Class({
}
},
/** */
getBorderColor:function () {
var model = this.getModel();
var result = model.getBorderColor();
@ -597,11 +639,13 @@ mindplot.Topic = new Class({
});
},
/** */
areChildrenShrunken:function () {
var model = this.getModel();
return model.areChildrenShrunken() && !this.isCentralTopic();
},
/** */
isCollapsed:function () {
var result = false;
@ -613,6 +657,7 @@ mindplot.Topic = new Class({
return result;
},
/** */
setChildrenShrunken:function (value) {
// Update Model ...
var model = this.getModel();
@ -647,6 +692,7 @@ mindplot.Topic = new Class({
},
/** */
getShrinkConnector:function () {
var result = this._connector;
if (this._connector == null) {
@ -658,11 +704,13 @@ mindplot.Topic = new Class({
return result;
},
/** */
handleMouseOver:function () {
var outerShape = this.getOuterShape();
outerShape.setOpacity(1);
},
/** */
handleMouseOut:function () {
var outerShape = this.getOuterShape();
if (!this.isOnFocus()) {
@ -670,10 +718,12 @@ mindplot.Topic = new Class({
}
},
/** */
showTextEditor:function (text) {
this._getTopicEventDispatcher().show(this, {text:text});
},
/** */
showNoteEditor:function () {
var topicId = this.getId();
@ -710,12 +760,14 @@ mindplot.Topic = new Class({
editor.show();
},
/** opens a dialog where the user can enter or edit an existing link associated with this topic */
showLinkEditor:function () {
var topicId = this.getId();
var model = this.getModel();
var editorModel = {
getValue:function () {
//@param {mindplot.model.LinkModel[]} links
var links = model.findFeatureByType(mindplot.TopicFeature.Link.id);
var result;
if (links.length > 0)
@ -747,6 +799,7 @@ mindplot.Topic = new Class({
editor.show();
},
/** */
closeEditors:function () {
this._getTopicEventDispatcher().close(true);
},
@ -784,10 +837,12 @@ mindplot.Topic = new Class({
this.invariant();
},
/** */
getOutgoingLine:function () {
return this._outgoingLine;
},
/** */
getIncomingLines:function () {
var result = [];
var children = this.getChildren();
@ -801,6 +856,7 @@ mindplot.Topic = new Class({
return result;
},
/** */
getOutgoingConnectedTopic:function () {
var result = null;
var line = this.getOutgoingLine();
@ -829,6 +885,7 @@ mindplot.Topic = new Class({
}
},
/** */
setBranchVisibility:function (value) {
var current = this;
var parent = this;
@ -839,7 +896,7 @@ mindplot.Topic = new Class({
current.setVisibility(value);
},
/** */
setVisibility:function (value) {
this._setTopicVisibility(value);
@ -856,6 +913,7 @@ mindplot.Topic = new Class({
}
},
/** */
moveToBack:function () {
// Update relationship lines
@ -870,6 +928,7 @@ mindplot.Topic = new Class({
this.get2DElement().moveToBack();
},
/** */
moveToFront:function () {
this.get2DElement().moveToFront();
@ -883,6 +942,7 @@ mindplot.Topic = new Class({
}
},
/** */
isVisible:function () {
var elem = this.get2DElement();
return elem.isVisible();
@ -914,6 +974,7 @@ mindplot.Topic = new Class({
textShape.setVisibility(this.getShapeType() != mindplot.model.TopicShape.IMAGE ? value : false);
},
/** */
setOpacity:function (opacity) {
var elem = this.get2DElement();
elem.setOpacity(opacity);
@ -943,6 +1004,7 @@ mindplot.Topic = new Class({
},
/** */
invariant:function () {
var line = this._outgoingLine;
var model = this.getModel();
@ -954,7 +1016,7 @@ mindplot.Topic = new Class({
}
},
/** */
setSize:function (size, force) {
$assert(size, "size can not be null");
$assert($defined(size.width), "size seem not to be a valid element");
@ -984,6 +1046,7 @@ mindplot.Topic = new Class({
$assert(false, "this method must be overwrited.");
},
/** */
disconnect:function (workspace) {
var outgoingLine = this.getOutgoingLine();
if ($defined(outgoingLine)) {
@ -1028,16 +1091,19 @@ mindplot.Topic = new Class({
}
},
/** */
getOrder:function () {
var model = this.getModel();
return model.getOrder();
},
/** */
setOrder:function (value) {
var model = this.getModel();
model.setOrder(value);
},
/** */
connectTo:function (targetTopic, workspace) {
$assert(!this._outgoingLine, 'Could not connect an already connected node');
$assert(targetTopic != this, 'Circular connection are not allowed');
@ -1090,16 +1156,19 @@ mindplot.Topic = new Class({
}
},
/** */
append:function (child) {
var children = this.getChildren();
children.push(child);
},
/** */
removeChild:function (child) {
var children = this.getChildren();
children.erase(child);
},
/** */
getChildren:function () {
var result = this._children;
if (!$defined(result)) {
@ -1109,6 +1178,7 @@ mindplot.Topic = new Class({
return result;
},
/** */
removeFromWorkspace:function (workspace) {
var elem2d = this.get2DElement();
workspace.removeChild(elem2d);
@ -1120,6 +1190,7 @@ mindplot.Topic = new Class({
mindplot.EventBus.instance.fireEvent(mindplot.EventBus.events.NodeRemoved, this.getModel());
},
/** */
addToWorkspace:function (workspace) {
var elem = this.get2DElement();
workspace.append(elem);
@ -1136,10 +1207,12 @@ mindplot.Topic = new Class({
this._adjustShapes();
},
/** */
isInWorkspace:function () {
return this._isInWorkspace;
},
/** */
createDragNode:function (layoutManager) {
var result = this.parent(layoutManager);
@ -1218,6 +1291,10 @@ mindplot.Topic = new Class({
return result;
},
/**
* @param childTopic
* @return {Boolean} true if childtopic is a child topic of this topic or the topic itself
*/
isChildTopic:function (childTopic) {
var result = (this.getId() == childTopic.getId());
if (!result) {
@ -1233,6 +1310,7 @@ mindplot.Topic = new Class({
return result;
},
/** @return {Boolean} true if the topic is the central topic of the map */
isCentralTopic:function () {
return this.getModel().getType() == mindplot.model.INodeModel.CENTRAL_TOPIC_TYPE;
}
@ -1240,10 +1318,29 @@ mindplot.Topic = new Class({
});
/**
* @constant
* @type {Number}
* @default
*/
mindplot.Topic.CONNECTOR_WIDTH = 6;
/**
* @constant
* @type {Object<String, Number>}
* @default
*/
mindplot.Topic.OUTER_SHAPE_ATTRIBUTES = {fillColor:'rgb(252,235,192)', stroke:'1 dot rgb(241,163,39)', x:0, y:0};
/**
* @constant
* @type {Object<String, Number>}
* @default
*/
mindplot.Topic.OUTER_SHAPE_ATTRIBUTES_FOCUS = {fillColor:'rgb(244,184,45)', x:0, y:0};
/**
* @constant
* @type {Object<String>}
* @default
* */
mindplot.Topic.INNER_RECT_ATTRIBUTES = {stroke:'2 solid'};

View File

@ -16,31 +16,47 @@
* limitations under the License.
*/
/** */
mindplot.TopicFeature = {
/** the icon object */
Icon:{
id:mindplot.model.IconModel.FEATURE_TYPE,
model:mindplot.model.IconModel,
icon:mindplot.ImageIcon
},
/** the link object */
Link:{
id:mindplot.model.LinkModel.FEATURE_TYPE,
model:mindplot.model.LinkModel,
icon:mindplot.LinkIcon
},
/** the note object */
Note:{
id:mindplot.model.NoteModel.FEATURE_TYPE,
model:mindplot.model.NoteModel,
icon:mindplot.NoteIcon
},
/**
* @param id the feature metadata id
* @return {Boolean} returns true if the given id is contained in the metadata array
*/
isSupported:function (id) {
return mindplot.TopicFeature._featuresMetadataById.some(function (elem) {
return elem.id == id;
});
},
/**
* @param type
* @param attributes
* @throws will throw an error if type is null or undefined
* @throws will throw an error if attributes is null or undefined
* @return {mindplot.model.FeatureModel} a new instance of the feature model subclass matching
* the topic feature
*/
createModel:function (type, attributes) {
$assert(type, 'type can not be null');
$assert(attributes, 'attributes can not be null');
@ -51,6 +67,14 @@ mindplot.TopicFeature = {
return new model(attributes);
},
/**
* @param {mindplot.Topic} topic
* @param {mindplot.model.FeatureModel} model
* @param {Boolean} readOnly true if the editor is running in read-only mode
* @throws will throw an error if topic 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
*/
createIcon:function (topic, model, readOnly) {
$assert(topic, 'topic can not be null');
$assert(model, 'model can not be null');

View File

@ -16,8 +16,18 @@
* limitations under the License.
*/
mindplot.commands.AddFeatureToTopicCommand = new Class({
mindplot.commands.AddFeatureToTopicCommand = new Class(/** @lends AddFeatureToTopicCommand */{
Extends:mindplot.Command,
/**
* @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}
* @constructs
* @param {String} topicId the id of the topic
* @param {String} featureType the id of the feature type to add, e.g. "icon"
* @param {Object} attributes the attribute(s) of the respective feature model
* @extends mindplot.Command
* @see mindplot.model.FeatureModel and subclasses
*/
initialize:function (topicId, featureType, attributes) {
$assert($defined(topicId), 'topicId can not be null');
@ -31,6 +41,9 @@ mindplot.commands.AddFeatureToTopicCommand = new Class({
this._featureModel = null;
},
/**
* Overrides abstract parent method
*/
execute:function (commandContext) {
var topic = commandContext.findTopics(this._topicId)[0];
@ -42,6 +55,10 @@ mindplot.commands.AddFeatureToTopicCommand = new Class({
topic.addFeature(this._featureModel);
},
/**
* Overrides abstract parent method
* @see {@link mindplot.Command.undoExecute}
*/
undoExecute:function (commandContext) {
var topic = commandContext.findTopics(this._topicId)[0];
topic.removeFeature(this._featureModel);

View File

@ -15,19 +15,34 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
mindplot.commands.AddRelationshipCommand = new Class({
mindplot.commands.AddRelationshipCommand = new Class(/** @lends AddRelationshipCommand */{
Extends:mindplot.Command,
/**
* @classdesc This command class handles do/undo of adding a relationship to a topic.
* @constructs
* @param {XMLDOM} model
* @extends mindplot.Command
*/
initialize:function (model) {
$assert(model, 'Relationship model can not be null');
this.parent();
this._model = model;
},
/**
* Overrides abstract parent method
*/
execute:function (commandContext) {
var relationship = commandContext.addRelationship(this._model);
relationship.setOnFocus(true);
},
/**
* Overrides abstract parent method
* @see {@link mindplot.Command.undoExecute}
*/
undoExecute:function (commandContext) {
var rel = commandContext.findRelationships(this._model.getId());
commandContext.deleteRelationship(rel[0]);

View File

@ -16,8 +16,17 @@
* limitations under the License.
*/
mindplot.commands.AddTopicCommand = new Class({
mindplot.commands.AddTopicCommand = new Class(/** @lends AddTopicCommand */{
Extends:mindplot.Command,
/**
* @classdesc This command class handles do/undo of adding one or multiple topics to
* the mindmap.
* @constructs
* @param {Array<mindplot.model.NodeModel>} models one or multiple models
* @param {Array<String>} parentTopicsId ids of the parent topics to add the children to, or null
* when attaching a dragged node or a node/branch from clipboard
* @extends mindplot.Command
*/
initialize:function (models, parentTopicsId) {
$assert(models, 'models can not be null');
$assert(parentTopicsId == null || parentTopicsId.length == models.length, 'parents and models must have the same size');
@ -27,6 +36,9 @@ mindplot.commands.AddTopicCommand = new Class({
this._parentsIds = parentTopicsId;
},
/**
* Overrides abstract parent method
*/
execute:function (commandContext) {
var me = this;
@ -57,6 +69,10 @@ mindplot.commands.AddTopicCommand = new Class({
});
},
/**
* Overrides abstract parent method
* @see {@link mindplot.Command.undoExecute}
*/
undoExecute:function (commandContext) {
// Delete disconnected the nodes. Create a copy of the topics ...
var clonedModel = [];

View File

@ -16,8 +16,18 @@
* limitations under the License.
*/
mindplot.commands.ChangeFeatureToTopicCommand = new Class({
mindplot.commands.ChangeFeatureToTopicCommand = new Class(/** @lends ChangeFeatureToTopicCommand */{
Extends:mindplot.Command,
/**
* @extends mindplot.Command
* @constructs
* @param topicId
* @param featureId
* @param attributes
* @throws will throw an error if topicId 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
*/
initialize: function(topicId, featureId, attributes) {
$assert($defined(topicId), 'topicId can not be null');
$assert($defined(featureId), 'featureId can not be null');
@ -29,6 +39,9 @@ mindplot.commands.ChangeFeatureToTopicCommand = new Class({
this._attributes = attributes;
},
/**
* Overrides abstract parent method
*/
execute: function(commandContext) {
var topic = commandContext.findTopics(this._topicId)[0];
var feature = topic.findFeatureById(this._featureId);
@ -38,6 +51,10 @@ mindplot.commands.ChangeFeatureToTopicCommand = new Class({
this._attributes = oldAttributes;
},
/**
* Overrides abstract parent method
* @see {@link mindplot.Command.undoExecute}
*/
undoExecute: function(commandContext) {
this.execute(commandContext);
}

View File

@ -16,8 +16,15 @@
* limitations under the License.
*/
mindplot.commands.DeleteCommand = new Class({
mindplot.commands.DeleteCommand = new Class(/** @lends mindplot.commands.DeleteCommand */{
Extends:mindplot.Command,
/**
* @classdesc This command class handles do/undo of deleting a topic.
* @constructs
* @param {Array<String>} topicIds ids of the topics to delete
* @param {Array<String>} relIds ids of the relationships connected to the topics
* @extends mindplot.Command
*/
initialize:function (topicIds, relIds) {
$assert($defined(relIds), 'topicIds can not be null');
@ -29,6 +36,9 @@ mindplot.commands.DeleteCommand = new Class({
this._parentTopicIds = [];
},
/**
* Overrides abstract parent method
*/
execute:function (commandContext) {
// If a parent has been selected for deletion, the children must be excluded from the delete ...
@ -76,6 +86,10 @@ mindplot.commands.DeleteCommand = new Class({
}
},
/**
* Overrides abstract parent method
* @see {@link mindplot.Command.undoExecute}
*/
undoExecute:function (commandContext) {
// Add all the topics ...

View File

@ -16,8 +16,17 @@
* limitations under the License.
*/
mindplot.commands.DragTopicCommand = new Class({
mindplot.commands.DragTopicCommand = new Class(/** @lends DragTopicCommand */{
Extends:mindplot.Command,
/**
* @classdesc This command class handles do/undo of dragging a topic to a new position.
* @constructs
* @param {String} topicId id of the topic to drag
* @param {Object} position
* @param {Number} order the order property (children of one node are displayed in order from 0 to n)
* @param {mindplot.Topic} parentTopic the topic to be made the dragged topic's new parent
* @extends mindplot.Command
*/
initialize:function (topicId, position, order, parentTopic) {
$assert(topicId, "topicId must be defined");
@ -30,6 +39,9 @@ mindplot.commands.DragTopicCommand = new Class({
this._order = order;
},
/**
* Overrides abstract parent method
*/
execute:function (commandContext) {
var topic = commandContext.findTopics(this._topicsId)[0];
@ -78,6 +90,10 @@ mindplot.commands.DragTopicCommand = new Class({
},
/**
* Overrides abstract parent method
* @see {@link mindplot.Command.undoExecute}
*/
undoExecute:function (commandContext) {
this.execute(commandContext);
}

View File

@ -16,8 +16,19 @@
* limitations under the License.
*/
mindplot.commands.GenericFunctionCommand = new Class({
mindplot.commands.GenericFunctionCommand = new Class(/** @lends GenericFunctionCommand */{
Extends:mindplot.Command,
/**
* @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
* StandaloneActionDispatcher i.e. the ActionDispatcher subclass in use)
* @constructs
* @param {Function} commandFunc the function the command shall execute
* @param {String|Array<String>} topicsIds the ids of the topics affected
* @param {Object} value arbitrary value necessary for the execution of the function,
* e.g. color, font family or text
* @extends mindplot.Command
*/
initialize:function (commandFunc, topicsIds, value) {
$assert(commandFunc, "commandFunc must be defined");
$assert($defined(topicsIds), "topicsIds must be defined");
@ -29,6 +40,9 @@ mindplot.commands.GenericFunctionCommand = new Class({
this._oldValues = [];
},
/**
* Overrides abstract parent method
*/
execute:function (commandContext) {
if (!this.applied) {
@ -60,6 +74,10 @@ mindplot.commands.GenericFunctionCommand = new Class({
},
/**
* Overrides abstract parent method
* @see {@link mindplot.Command.undoExecute}
*/
undoExecute:function (commandContext) {
if (this.applied) {
var topics = commandContext.findTopics(this._topicsId);

View File

@ -15,8 +15,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
mindplot.commands.MoveControlPointCommand = new Class({
mindplot.commands.MoveControlPointCommand = new Class(/** @lends MoveControlPointCommand */{
Extends:mindplot.Command,
/**
* @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
* influence how the arrow is drawn (not the source or the destination topic nor the arrow
* direction)
* @constructs
* @param {ControlPoint} ctrlPointController
* @param {Number} point 0 for the destination control point, 1 for the source control point
* @param ctrlPointController {ControlPoint}
* @param point {Number} 0 for the destination control point, 1 for the source control point
*/
initialize:function (ctrlPointController, point) {
$assert(ctrlPointController, 'line can not be null');
$assert($defined(point), 'point can not be null');
@ -40,6 +52,9 @@ mindplot.commands.MoveControlPointCommand = new Class({
this._point = point;
},
/**
* Overrides abstract parent method
*/
execute:function (commandContext) {
var model = this._line.getModel();
switch (this._point) {
@ -64,6 +79,10 @@ mindplot.commands.MoveControlPointCommand = new Class({
this._line.getLine().updateLine(this._point);
},
/**
* Overrides abstract parent method
* @see {@link mindplot.Command.undoExecute}
*/
undoExecute:function (commandContext) {
var line = this._line;
var model = line.getModel();

View File

@ -16,8 +16,16 @@
* limitations under the License.
*/
mindplot.commands.RemoveFeatureFromTopicCommand = new Class({
mindplot.commands.RemoveFeatureFromTopicCommand = new Class(/**@lends RemoveFeatureFromTopicCommand */{
Extends:mindplot.Command,
/**
* @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}.
* @constructs
* @param {String} topicId id of the topic to remove the feature from
* @param {String} featureId id of the feature to remove
* @extends mindplot.Command
*/
initialize:function (topicId, featureId) {
$assert($defined(topicId), 'topicId can not be null');
$assert(featureId, 'iconModel can not be null');
@ -28,6 +36,9 @@ mindplot.commands.RemoveFeatureFromTopicCommand = new Class({
this._oldFeature = null;
},
/**
* Overrides abstract parent method
*/
execute:function (commandContext) {
var topic = commandContext.findTopics(this._topicId)[0];
var feature = topic.findFeatureById(this._featureId);
@ -35,6 +46,10 @@ mindplot.commands.RemoveFeatureFromTopicCommand = new Class({
this._oldFeature = feature;
},
/**
* Overrides abstract parent method
* @see {@link mindplot.Command.undoExecute}
*/
undoExecute:function (commandContext) {
var topic = commandContext.findTopics(this._topicId)[0];
topic.addFeature(this._oldFeature);

View File

@ -16,9 +16,18 @@
* limitations under the License.
*/
mindplot.layout.AbstractBasicSorter = new Class({
/**
* @class
* @extends mindplot.layout.ChildrenSorterStrategy
*/
mindplot.layout.AbstractBasicSorter = new Class(/** @lends AbstractBasicSorter */{
Extends: mindplot.layout.ChildrenSorterStrategy,
/**
* @param {} treeSet
* @param {} node
* @return the height of a node and its children if existing and not shrunken
*/
computeChildrenIdByHeights: function(treeSet, node) {
var result = {};
this._computeChildrenHeight(treeSet, node, result);
@ -67,5 +76,15 @@ mindplot.layout.AbstractBasicSorter = new Class({
});
/**
* @constant
* @type {Number}
* @default
*/
mindplot.layout.AbstractBasicSorter.INTERNODE_VERTICAL_PADDING = 5;
/**
* @constant
* @type {Number}
* @default
*/
mindplot.layout.AbstractBasicSorter.INTERNODE_HORIZONTAL_PADDING = 30;

View File

@ -15,13 +15,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
mindplot.layout.BalancedSorter = new Class({
Extends:mindplot.layout.AbstractBasicSorter,
mindplot.layout.BalancedSorter = new Class(/** @lends BalancedSorter */{
Extends:mindplot.layout.AbstractBasicSorter,
/**
* @constructs
* @extends mindplot.layout.AbstractBasicSorter
*/
initialize:function () {
},
/**
* @param {} graph
* @param {} parent
* @param {} node
* @param {} position
* @param {Boolean} free
* @return an array with order and position
*/
predict:function (graph, parent, node, position, free) {
// If its a free node...
if (free) {
@ -99,6 +111,12 @@ mindplot.layout.BalancedSorter = new Class({
return result;
},
/**
* @param {} treeSet
* @param {} parent
* @param {} child
* @param {} order
*/
insert:function (treeSet, parent, child, order) {
var children = this._getChildrenForOrder(parent, treeSet, order);
@ -124,6 +142,10 @@ mindplot.layout.BalancedSorter = new Class({
child.setOrder(newOrder);
},
/**
* @param {} treeSet
* @param {} node
*/
detach:function (treeSet, node) {
var parent = treeSet.getParent(node);
// Filter nodes on one side..
@ -137,6 +159,11 @@ mindplot.layout.BalancedSorter = new Class({
node.setOrder(node.getOrder() % 2 == 0 ? 0 : 1);
},
/**
* @param {} treeSet
* @param {} node
* @return offsets
*/
computeOffsets:function (treeSet, node) {
$assert(treeSet, "treeSet can no be null.");
$assert(node, "node can no be null.");
@ -189,6 +216,11 @@ mindplot.layout.BalancedSorter = new Class({
return result;
},
/**
* @param {} treeSet
* @param {} node
* @throw will throw an error if order elements are missing
*/
verify:function (treeSet, node) {
// Check that all is consistent ...
var children = this._getChildrenForOrder(node, treeSet, node.getOrder());
@ -202,10 +234,18 @@ mindplot.layout.BalancedSorter = new Class({
}
},
/**
* @param {} treeSet
* @param {} child
* @return the direction of the child within the treeSet
*/
getChildDirection:function (treeSet, child) {
return child.getOrder() % 2 == 0 ? 1 : -1;
},
/**
* @return {String} the print name of this class
*/
toString:function () {
return "Balanced Sorter";
},
@ -221,5 +261,15 @@ mindplot.layout.BalancedSorter = new Class({
}
});
/**
* @constant
* @type {Number}
* @default
*/
mindplot.layout.BalancedSorter.INTERNODE_VERTICAL_PADDING = 5;
/**
* @constant
* @type {Number}
* @default
*/
mindplot.layout.BalancedSorter.INTERNODE_HORIZONTAL_PADDING = 30;

View File

@ -15,7 +15,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
mindplot.layout.ChangeEvent = new Class({
mindplot.layout.ChangeEvent = new Class(/** @lends ChangeEvent */{
/**
* @constructs
* @param {} id
* @throws will throw an error if the given id is not/cannot be converted to a numerical value
*/
initialize:function(id) {
$assert(!isNaN(id), "id can not be null");
this._id = id;
@ -23,28 +29,39 @@ mindplot.layout.ChangeEvent = new Class({
this._order = null;
},
/** @return id */
getId:function() {
return this._id;
},
/** @return order */
getOrder: function() {
return this._order;
},
/** @return position */
getPosition: function() {
return this._position;
},
/**
* @param {} value the order to set
* @throws will throw an error if the given parameter is not/cannot be converted to a numerical
* value
*/
setOrder: function(value) {
$assert(!isNaN(value), "value can not be null");
this._order = value;
},
/** @param {} value
* @throws will throw an error if the value is null or undefined*/
setPosition: function(value) {
$assert(value, "value can not be null");
this._position = value;
},
/** @return {String} order and position */
toString: function() {
return "[order:" + this.getOrder() + ", position: {" + this.getPosition().x + "," + this.getPosition().y + "}]";
}

View File

@ -15,39 +15,51 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
mindplot.layout.ChildrenSorterStrategy = new Class({
mindplot.layout.ChildrenSorterStrategy = new Class(/** @lends ChildrenSorterStrategy */{
/**
* @constructs
*/
initialize:function() {
},
/** @abstract */
computeChildrenIdByHeights: function(treeSet, node) {
throw "Method must be implemented";
},
/** @abstract */
computeOffsets:function(treeSet, node) {
throw "Method must be implemented";
},
/** @abstract */
insert: function(treeSet, parent, child, order) {
throw "Method must be implemented";
},
/** @abstract */
detach:function(treeSet, node) {
throw "Method must be implemented";
},
/** @abstract */
predict:function(treeSet, parent, node, position, free) {
throw "Method must be implemented";
},
/** @abstract */
verify:function(treeSet, node) {
throw "Method must be implemented";
},
/** @abstract */
getChildDirection: function(treeSet, node) {
throw "Method must be implemented";
},
/** @abstract */
toString:function() {
throw "Method must be implemented: print name";
}

View File

@ -15,12 +15,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
mindplot.EventBus = new Class({
mindplot.EventBus = new Class(/** @lends EventBus */{
Implements: mindplot.Events,
/**
* @constructs
* @implements mindplot.Events
*/
initialize: function() {
}
});
/**
* Enum for events
* @enum {String}
*/
mindplot.EventBus.events = {
NodeResizeEvent:'NodeResizeEvent',
NodeMoveEvent:'NodeMoveEvent',
@ -32,4 +41,5 @@ mindplot.EventBus.events = {
DoLayout:'DoLayout'
};
/** instance */
mindplot.EventBus.instance = new mindplot.EventBus();

View File

@ -15,16 +15,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
mindplot.layout.EventBusDispatcher = new Class({
mindplot.layout.EventBusDispatcher = new Class(/** @lends EventBusDispatcher */{
/**
* @constructs
*/
initialize:function() {
this.registerBusEvents();
},
/**
* @param {mindplot.layout.LayoutManager} layoutManager
*/
setLayoutManager : function(layoutManager) {
this._layoutManager = layoutManager;
},
/**
* register bus events
*/
registerBusEvents:function () {
mindplot.EventBus.instance.addEvent(mindplot.EventBus.events.NodeAdded, this._nodeAdded.bind(this));
mindplot.EventBus.instance.addEvent(mindplot.EventBus.events.NodeRemoved, this._nodeRemoved.bind(this));
@ -79,6 +88,7 @@ mindplot.layout.EventBusDispatcher = new Class({
// }).delay(0, this);
},
/** @return layout manager */
getLayoutManager: function() {
return this._layoutManager;
}

View File

@ -15,9 +15,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
mindplot.layout.GridSorter = new Class({
/**
* @class
* @extends mindplot.layout.AbstractBasicSorter
*/
mindplot.layout.GridSorter = new Class(/** @lends GridSorter */{
Extends: mindplot.layout.AbstractBasicSorter,
/**
* @param {} treeSet
* @param {} node
* @return offsets
*/
computeOffsets: function(treeSet, node) {
$assert(treeSet, "treeSet can no be null.");
$assert(node, "node can no be null.");
@ -58,12 +68,25 @@ mindplot.layout.GridSorter = new Class({
return result;
},
/**
* @return {String} the print name of this class
*/
toString:function() {
return "Grid Sorter";
}
});
/**
* @constant
* @type {Number}
* @default
*/
mindplot.layout.GridSorter.GRID_HORIZONTAR_SIZE = 20;
/**
* @constant
* @type {Number}
* @default
*/
mindplot.layout.GridSorter.INTER_NODE_VERTICAL_DISTANCE = 50;

View File

@ -15,8 +15,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
mindplot.layout.LayoutManager = new Class({
mindplot.layout.LayoutManager = new Class(/** @lends LayoutManager */{
Extends: mindplot.Events,
/**
* @constructs
* @extends mindplot.Events
* @param {} rootNodeId
* @param {} rootSize
* @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
*/
initialize: function(rootNodeId, rootSize) {
$assert($defined(rootNodeId), "rootNodeId can not be null");
$assert(rootSize, "rootSize can not be null");
@ -30,6 +39,11 @@ mindplot.layout.LayoutManager = new Class({
this._events = [];
},
/**
* @param id
* @param size
* @throws will throw an error if id is null or undefined
*/
updateNodeSize: function(id, size) {
$assert($defined(id), "id can not be null");
@ -37,6 +51,13 @@ mindplot.layout.LayoutManager = new Class({
node.setSize(size);
},
/**
* @param id
* @param value
* @throws will throw an error if id is null or undefined
* @throws will throw an error if value is null or undefined
* @return this
*/
updateShrinkState: function(id, value) {
$assert($defined(id), "id can not be null");
$assert($defined(value), "value can not be null");
@ -47,10 +68,22 @@ mindplot.layout.LayoutManager = new Class({
return this;
},
/**
* @param id
* @return {@link RootedTreeSet}.find(id)
*/
find: function(id) {
return this._treeSet.find(id);
},
/**
* @param id
* @param position
* @throws will throw an error if id is null or undefined
* @throws will throw an error if position 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
*/
moveNode: function(id, position) {
$assert($defined(id), "id cannot be null");
$assert($defined(position), "position cannot be null");
@ -64,6 +97,15 @@ mindplot.layout.LayoutManager = new Class({
node.setPosition(position);
},
/**
* @param parentId
* @param childId
* @param order
* @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 order is null or undefined
* @return this
*/
connectNode: function(parentId, childId, order) {
$assert($defined(parentId), "parentId cannot be null");
$assert($defined(childId), "childId cannot be null");
@ -74,6 +116,11 @@ mindplot.layout.LayoutManager = new Class({
return this;
},
/**
* @param id
* @throws will throw an error if id is null or undefined
* @return this
*/
disconnectNode: function(id) {
$assert($defined(id), "id can not be null");
this._layout.disconnectNode(id);
@ -81,6 +128,13 @@ mindplot.layout.LayoutManager = new Class({
return this;
},
/**
* @param id
* @param size
* @param position
* @throws will throw an error if id is null or undefined
* @return this
*/
addNode:function(id, size, position) {
$assert($defined(id), "id can not be null");
var result = this._layout.createNode(id, size, position, 'topic');
@ -89,6 +143,12 @@ mindplot.layout.LayoutManager = new Class({
return this;
},
/**
* removes a node and its connection to parent if existing
* @param id
* @throws will throw an error if id is null or undefined
* @return this
*/
removeNode: function(id) {
$assert($defined(id), "id can not be null");
var node = this._treeSet.find(id);
@ -104,6 +164,14 @@ mindplot.layout.LayoutManager = new Class({
return this;
},
/**
* @param {Number} parentId
* @param {Number=} nodeId
* @param {String=} position the position to use as mindplot.layout.Node.properties position
* property as '(x,y)'
* @param {Boolean=} free true specifies free node positioning
* @throws will throw an error if parentId is null or undefined
*/
predict: function(parentId, nodeId, position, free) {
$assert($defined(parentId), "parentId can not be null");
@ -115,10 +183,19 @@ mindplot.layout.LayoutManager = new Class({
return {order:result[0],position:result[1]};
},
/**
* logs dump to console
*/
dump: function() {
console.log(this._treeSet.dump());
},
/**
* @param containerId
* @param {width:Number, height:Number} size
* @throws will throw an error if containerId is null or undefined
* @return canvas
*/
plot: function(containerId, size) {
$assert(containerId, "containerId cannot be null");
size = size || {width:200,height:200};
@ -130,6 +207,11 @@ mindplot.layout.LayoutManager = new Class({
return canvas;
},
/**
* initializes the layout to be updated
* @param fireEvents
* @return this
*/
layout: function(fireEvents) {
// File repositioning ...
this._layout.layout();

View File

@ -15,7 +15,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
mindplot.layout.Node = new Class({
mindplot.layout.Node = new Class(/** @lends Node */{
/**
* @constructs
* @param id
* @param size
* @param position
* @param sorter
* @throws will throw an error if id is not a finite number or is null or undefined
* @throws will throw an error if size 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
*/
initialize:function (id, size, position, sorter) {
$assert(typeof id === 'number' && isFinite(id), "id can not be null");
$assert(size, "size can not be null");
@ -31,39 +43,48 @@ mindplot.layout.Node = new Class({
this.setShrunken(false);
},
/** */
getId:function () {
return this._id;
},
/** */
setFree:function (value) {
this._setProperty('free', value);
},
/** */
isFree:function () {
return this._getProperty('free');
},
/** */
hasFreeChanged:function () {
return this._isPropertyChanged('free');
},
/** */
hasFreeDisplacementChanged:function () {
return this._isPropertyChanged('freeDisplacement');
},
/** */
setShrunken:function (value) {
this._setProperty('shrink', value);
},
/** */
areChildrenShrunken:function () {
return this._getProperty('shrink');
},
/** */
setOrder:function (order) {
$assert(typeof order === 'number' && isFinite(order), "Order can not be null. Value:" + order);
this._setProperty('order', order);
},
/** */
resetPositionState:function () {
var prop = this._properties['position'];
if (prop) {
@ -71,6 +92,7 @@ mindplot.layout.Node = new Class({
}
},
/** */
resetOrderState:function () {
var prop = this._properties['order'];
if (prop) {
@ -78,6 +100,7 @@ mindplot.layout.Node = new Class({
}
},
/** */
resetFreeState:function () {
var prop = this._properties['freeDisplacement'];
if (prop) {
@ -85,35 +108,43 @@ mindplot.layout.Node = new Class({
}
},
/** */
getOrder:function () {
return this._getProperty('order');
},
/** */
hasOrderChanged:function () {
return this._isPropertyChanged('order');
},
/** */
hasPositionChanged:function () {
return this._isPropertyChanged('position');
},
/** */
hasSizeChanged:function () {
return this._isPropertyChanged('size');
},
/** */
getPosition:function () {
return this._getProperty('position');
},
/** */
setSize:function (size) {
$assert($defined(size), "Size can not be null");
this._setProperty('size', Object.clone(size));
},
/** */
getSize:function () {
return this._getProperty('size');
},
/** */
setFreeDisplacement:function (displacement) {
$assert($defined(displacement), "Position can not be null");
$assert($defined(displacement.x), "x can not be null");
@ -124,15 +155,18 @@ mindplot.layout.Node = new Class({
this._setProperty('freeDisplacement', Object.clone(newDisplacement));
},
/** */
resetFreeDisplacement:function () {
this._setProperty('freeDisplacement', {x:0, y:0});
},
/** */
getFreeDisplacement:function () {
var freeDisplacement = this._getProperty('freeDisplacement');
return (freeDisplacement || {x:0, y:0});
},
/** */
setPosition:function (position) {
$assert($defined(position), "Position can not be null");
$assert($defined(position.x), "x can not be null");
@ -173,10 +207,12 @@ mindplot.layout.Node = new Class({
return prop ? prop.hasChanged : false;
},
/** */
getSorter:function () {
return this._sorter;
},
/** @return {String} returns id, order, position, size and shrink information*/
toString:function () {
return "[id:" + this.getId() + ", order:" + this.getOrder() + ", position: {" + this.getPosition().x + "," + this.getPosition().y + "}, size: {" + this.getSize().width + "," + this.getSize().height + "}, shrink:" + this.areChildrenShrunken() + "]";
}

View File

@ -15,11 +15,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
mindplot.layout.OriginalLayout = new Class({
mindplot.layout.OriginalLayout = new Class(/** @lends OriginalLayout */{
/**
* @constructs
* @param treeSet
*/
initialize:function (treeSet) {
this._treeSet = treeSet;
},
/** */
createNode:function (id, size, position, type) {
$assert($defined(id), "id can not be null");
$assert(size, "size can not be null");
@ -32,6 +38,7 @@ mindplot.layout.OriginalLayout = new Class({
return new mindplot.layout.Node(id, size, position, strategy);
},
/** */
connectNode:function (parentId, childId, order) {
var parent = this._treeSet.find(parentId);
@ -48,6 +55,7 @@ mindplot.layout.OriginalLayout = new Class({
sorter.verify(this._treeSet, parent);
},
/** */
disconnectNode:function (nodeId) {
var node = this._treeSet.find(nodeId);
var parent = this._treeSet.getParent(node);
@ -68,6 +76,7 @@ mindplot.layout.OriginalLayout = new Class({
parent.getSorter().verify(this._treeSet, parent);
},
/** */
layout:function () {
var roots = this._treeSet.getTreeRoots();
_.each(roots, function (node) {
@ -233,7 +242,14 @@ mindplot.layout.OriginalLayout = new Class({
});
/**
* @type {mindplot.layout.SymmetricSorter}
*/
mindplot.layout.OriginalLayout.SYMMETRIC_SORTER = new mindplot.layout.SymmetricSorter();
/**
* @type {mindplot.layout.BalancedSorter}
*/
mindplot.layout.OriginalLayout.BALANCED_SORTER = new mindplot.layout.BalancedSorter();

View File

@ -15,16 +15,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
mindplot.layout.RootedTreeSet = new Class({
mindplot.layout.RootedTreeSet = new Class(/** @lends RootedTreeSet */{
/** @constructs */
initialize:function () {
this._rootNodes = [];
},
/**
* @param root
* @throws will throw an error if root is null or undefined
*/
setRoot:function (root) {
$assert(root, 'root can not be null');
this._rootNodes.push(this._decodate(root));
},
/** getter */
getTreeRoots:function () {
return this._rootNodes;
},
@ -34,6 +41,12 @@ mindplot.layout.RootedTreeSet = new Class({
return node;
},
/**
* @param {mindplot.model.NodeModel} node
* @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 has been added already
*/
add:function (node) {
$assert(node, 'node can not be null');
$assert(!this.find(node.getId(), false), 'node already exits with this id. Id:' + node.getId());
@ -42,12 +55,23 @@ mindplot.layout.RootedTreeSet = new Class({
},
/**
* @param nodeId
* @throws will throw an error if nodeId is null or undefined
*/
remove:function (nodeId) {
$assert($defined(nodeId), 'nodeId can not be null');
var node = this.find(nodeId);
this._rootNodes.erase(node);
},
/**
* @param parentId
* @param childId
* @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 node with id childId is already a child of parent
*/
connect:function (parentId, childId) {
$assert($defined(parentId), 'parent can not be null');
$assert($defined(childId), 'child can not be null');
@ -61,6 +85,11 @@ mindplot.layout.RootedTreeSet = new Class({
this._rootNodes.erase(child);
},
/**
* @param nodeId
* @throws will throw an error if nodeId is null or undefined
* @throws will throw an error if node is not connected
*/
disconnect:function (nodeId) {
$assert($defined(nodeId), 'nodeId can not be null');
var node = this.find(nodeId);
@ -71,6 +100,13 @@ mindplot.layout.RootedTreeSet = new Class({
node._parent = null;
},
/**
* @param id
* @param validate
* @throws will throw an error if id is null or undefined
* @throws will throw an error if node cannot be found
* @return node
*/
find:function (id, validate) {
$assert($defined(id), 'id can not be null');
@ -107,11 +143,21 @@ mindplot.layout.RootedTreeSet = new Class({
return result;
},
/**
* @param node
* @throws will throw an error if nodeId is null or undefined
* @return children
*/
getChildren:function (node) {
$assert(node, 'node cannot be null');
return node._children;
},
/**
* @param node
* @throws will throw an error if node is null or undefined
* @return root node or the provided node, if it has no parent
*/
getRootNode:function (node) {
$assert(node, "node cannot be null");
var parent = this.getParent(node);
@ -122,6 +168,10 @@ mindplot.layout.RootedTreeSet = new Class({
return node;
},
/**
* @param node
* @throws will throw an error if node is null or undefined
* @return {Array} ancestors*/
getAncestors:function (node) {
$assert(node, 'node cannot be null');
return this._getAncestors(this.getParent(node), []);
@ -136,6 +186,11 @@ mindplot.layout.RootedTreeSet = new Class({
return result;
},
/**
* @param node
* @throws will throw an error if node is null or undefined
* @return {Array} siblings
*/
getSiblings:function (node) {
$assert(node, 'node cannot be null');
if (!$defined(node._parent)) {
@ -147,6 +202,11 @@ mindplot.layout.RootedTreeSet = new Class({
return siblings;
},
/**
* @param node
* @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)
*/
hasSinglePathToSingleLeaf:function (node) {
$assert(node, 'node cannot be null');
return this._hasSinglePathToSingleLeaf(node);
@ -162,20 +222,36 @@ mindplot.layout.RootedTreeSet = new Class({
return children.length == 0;
},
/**
* @param node
* @return {Boolean} whether the node is the start of a subbranch*/
isStartOfSubBranch:function (node) {
return this.getSiblings(node).length > 0 && this.getChildren(node).length == 1;
},
/**
* @param node
* @throws will throw an error if node is null or undefined
* @return {Boolean} whether the node is a leaf
*/
isLeaf:function (node) {
$assert(node, 'node cannot be null');
return this.getChildren(node).length == 0;
},
/**
* @param node
* @throws will throw an error if node is null or undefined
* @return parent
*/
getParent:function (node) {
$assert(node, 'node cannot be null');
return node._parent;
},
/**
* @return result
*/
dump:function () {
var branches = this._rootNodes;
var result = "";
@ -197,6 +273,9 @@ mindplot.layout.RootedTreeSet = new Class({
return result;
},
/**
* @param canvas
*/
plot:function (canvas) {
var branches = this._rootNodes;
for (var i = 0; i < branches.length; i++) {
@ -231,6 +310,10 @@ mindplot.layout.RootedTreeSet = new Class({
}
},
/**
* @param node
* @param position
*/
updateBranchPosition:function (node, position) {
var oldPos = node.getPosition();
@ -247,6 +330,11 @@ mindplot.layout.RootedTreeSet = new Class({
},
/**
* @param node
* @param xOffset
* @param yOffset
*/
shiftBranchPosition:function (node, xOffset, yOffset) {
var position = node.getPosition();
node.setPosition({x:position.x + xOffset, y:position.y + yOffset});
@ -258,6 +346,11 @@ mindplot.layout.RootedTreeSet = new Class({
});
},
/**
* @param node
* @param yOffset
* @return siblings in the offset (vertical) direction, i.e. with lower or higher order, respectively
*/
getSiblingsInVerticalDirection:function (node, yOffset) {
// 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);
@ -274,6 +367,12 @@ mindplot.layout.RootedTreeSet = new Class({
return siblings;
},
/**
* @param node
* @param yOffset
* @return branches of the root node on the same side as the given node's, in the given
* vertical direction
*/
getBranchesInVerticalDirection:function (node, yOffset) {
// direct descendants of the root that do not contain the node and are on the same side
// and on the direction of the offset

View File

@ -15,8 +15,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
mindplot.layout.SymmetricSorter = new Class({
mindplot.layout.SymmetricSorter = new Class(/** @lends SymmetricSorter */{
Extends:mindplot.layout.AbstractBasicSorter,
/**
* @constructs
* @extends mindplot.layout.AbstractBasicSorter
*/
initialize:function () {
},
@ -128,6 +133,13 @@ mindplot.layout.SymmetricSorter = new Class({
return [0, position];
},
/**
* @param treeSet
* @param parent
* @param child
* @param order
* @throws will throw an error if the order is not strictly continuous
*/
insert:function (treeSet, parent, child, order) {
var children = this._getSortedChildren(treeSet, parent);
$assert(order <= children.length, "Order must be continues and can not have holes. Order:" + order);
@ -140,6 +152,10 @@ mindplot.layout.SymmetricSorter = new Class({
child.setOrder(order);
},
/**
* @param treeSet
* @param node
* @throws will throw an error if the node is in the wrong position*/
detach:function (treeSet, node) {
var parent = treeSet.getParent(node);
var children = this._getSortedChildren(treeSet, parent);
@ -154,6 +170,17 @@ mindplot.layout.SymmetricSorter = new Class({
node.setOrder(0);
},
/**
* @param treeSet
* @param node
* @throws will throw an error if treeSet is null or undefined
* @throws will throw an error if node is null or undefined
* @throws will throw an error if the calculated x offset cannot be converted to a numeric
* value, is null or undefined
* @throws will throw an error if the calculated y offset cannot be converted to a numeric
* value, is null or undefined
* @return offsets
*/
computeOffsets:function (treeSet, node) {
$assert(treeSet, "treeSet can no be null.");
$assert(node, "node can no be null.");
@ -191,6 +218,11 @@ mindplot.layout.SymmetricSorter = new Class({
return result;
},
/**
* @param treeSet
* @param node
* @throws will throw an error if order elements are missing
*/
verify:function (treeSet, node) {
// Check that all is consistent ...
var children = this._getSortedChildren(treeSet, node);
@ -200,6 +232,10 @@ mindplot.layout.SymmetricSorter = new Class({
}
},
/**
* @param treeSet
* @param child
* @return direction of the given child from its parent or from the root node, if isolated*/
getChildDirection:function (treeSet, child) {
$assert(treeSet, "treeSet can no be null.");
$assert(treeSet.getParent(child), "This should not happen");
@ -220,6 +256,7 @@ mindplot.layout.SymmetricSorter = new Class({
return result;
},
/** @return {String} the print name of this class */
toString:function () {
return "Symmetric Sorter";
},
@ -229,7 +266,17 @@ mindplot.layout.SymmetricSorter = new Class({
}
});
/**
* @constant
* @type {Number}
* @default
*/
mindplot.layout.SymmetricSorter.INTERNODE_VERTICAL_PADDING = 5;
/**
* @constant
* @type {Number}
* @default
*/
mindplot.layout.SymmetricSorter.INTERNODE_HORIZONTAL_PADDING = 30;

View File

@ -16,7 +16,7 @@
* limitations under the License.
*/
mindplot.model.FeatureModel = new Class({
mindplot.model.FeatureModel = new Class(/** @lends FeatureModel */{
Static:{
_nextUUID:function () {
if (!$defined(mindplot.model.FeatureModel._uuid)) {
@ -28,6 +28,12 @@ mindplot.model.FeatureModel = new Class({
}
},
/**
* @constructs
* @param type
* @throws will throw an exception if type is null or undefined
* assigns a unique id and the given type to the new model
*/
initialize:function (type) {
$assert(type, 'type can not be null');
this._id = mindplot.model.FeatureModel._nextUUID();
@ -41,35 +47,42 @@ mindplot.model.FeatureModel = new Class({
};
},
/** */
getAttributes:function () {
return Object.clone(this._attributes);
},
/** */
setAttributes:function (attributes) {
for (key in attributes) {
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;
}

View File

@ -15,55 +15,76 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
mindplot.model.IMindmap = new Class({
mindplot.model.IMindmap = new Class(/** @lends IMindmap */{
/**
* @constructs
* @abstract
*/
initialize : function() {
throw "Unsupported operation";
},
/** */
getCentralTopic : function() {
return this.getBranches()[0];
},
/** @abstract */
getDescription : function() {
throw "Unsupported operation";
},
/** @abstract */
setDescription : function(value) {
throw "Unsupported operation";
},
/** @abstract */
getId : function() {
throw "Unsupported operation";
},
/** @abstract */
setId : function(id) {
throw "Unsupported operation";
},
/** @abstract */
getVersion : function() {
throw "Unsupported operation";
},
/** @abstract */
setVersion : function(version) {
throw "Unsupported operation";
},
/** @abstract */
addBranch : function(nodeModel) {
throw "Unsupported operation";
},
/** @abstract */
getBranches : function() {
throw "Unsupported operation";
},
/** @abstract */
removeBranch : function(node) {
throw "Unsupported operation";
},
/** @abstract */
getRelationships : function() {
throw "Unsupported operation";
},
/**
* @param parent
* @param child
* @throws will throw an error if child already has a connection to a parent node
*/
connect : function(parent, child) {
// Child already has a parent ?
$assert(!child.getParent(), 'Child model seems to be already connected');
@ -75,6 +96,11 @@ mindplot.model.IMindmap = new Class({
this.removeBranch(child);
},
/**
* @param child
* @throws will throw an error if child is null or undefined
* @throws will throw an error if child's parent cannot be found
*/
disconnect : function(child) {
var parent = child.getParent();
$assert(child, 'Child can not be null.');
@ -84,26 +110,32 @@ mindplot.model.IMindmap = new Class({
this.addBranch(child);
},
/** @abstract */
hasAlreadyAdded : function(node) {
throw "Unsupported operation";
},
/** @abstract */
createNode : function(type, id) {
throw "Unsupported operation";
},
/** @abstract */
createRelationship : function(fromNode, toNode) {
throw "Unsupported operation";
},
/** @abstract */
addRelationship : function(rel) {
throw "Unsupported operation";
},
/** @abstract */
deleteRelationship : function(relationship) {
throw "Unsupported operation";
},
/** */
inspect : function() {
var result = '';
result = '{ ';
@ -125,6 +157,9 @@ mindplot.model.IMindmap = new Class({
return result;
},
/**
* @param target
*/
copyTo : function(target) {
var source = this;
var version = source.getVersion();

View File

@ -16,16 +16,22 @@
* limitations under the License.
*/
mindplot.model.INodeModel = new Class({
mindplot.model.INodeModel = new Class(/** @lends INodeModel */{
/**
* @constructs
* @param mindmap
*/
initialize: function(mindmap) {
$assert(mindmap && mindmap.getBranches, 'mindmap can not be null');
this._mindmap = mindmap;
},
/** */
getId : function() {
return this.getProperty('id');
},
/** */
setId : function(id) {
if ($defined(id) && id > mindplot.model.INodeModel._uuid) {
mindplot.model.INodeModel._uuid = id;
@ -38,28 +44,34 @@ mindplot.model.INodeModel = new Class({
},
/** */
getType : function() {
return this.getProperty('type');
},
/** */
setType : function(type) {
this.putProperty('type', type);
},
/** */
setText : function(text) {
this.putProperty('text', text);
},
/** */
getText : function() {
return this.getProperty('text');
},
/** */
setPosition : function(x, y) {
$assert(!isNaN(parseInt(x)), "x position is not valid:" + x);
$assert(!isNaN(parseInt(y)), "y position is not valid:" + y);
this.putProperty('position', '{x:' + parseInt(x) + ',y:' + parseInt(y) + '}');
},
/** */
getPosition : function() {
var value = this.getProperty('position');
var result = null;
@ -69,10 +81,12 @@ mindplot.model.INodeModel = new Class({
return result;
},
/** */
setImageSize : function(width, height) {
this.putProperty('imageSize', '{width:' + width + ',height:' + height + '}');
},
/** */
getImageSize : function() {
var value = this.getProperty('imageSize');
var result = null;
@ -82,133 +96,180 @@ mindplot.model.INodeModel = new Class({
return result;
},
/** */
setImageUrl:function(url) {
this.putProperty('imageUrl', url);
},
/** */
getMetadata:function() {
return this.getProperty('metadata');
},
/** */
setMetadata:function(json) {
this.putProperty('metadata', json);
},
/** */
getImageUrl:function() {
return this.getProperty('imageUrl');
},
/** */
getMindmap : function() {
return this._mindmap;
},
/**
* lets the mindmap handle the disconnect node operation
* @see mindplot.model.IMindmap.disconnect
*/
disconnect : function() {
var mindmap = this.getMindmap();
mindmap.disconnect(this);
},
/** */
getShapeType : function() {
return this.getProperty('shapeType');
},
/** */
setShapeType : function(type) {
this.putProperty('shapeType', type);
},
/** */
setOrder : function(value) {
$assert(typeof value === 'number' && isFinite(value) || value == null, "Order must be null or a number");
this.putProperty('order', value);
},
/** */
getOrder : function() {
return this.getProperty('order');
},
/** */
setFontFamily : function(fontFamily) {
this.putProperty('fontFamily', fontFamily);
},
/** */
getFontFamily : function() {
return this.getProperty('fontFamily');
},
/** */
setFontStyle : function(fontStyle) {
this.putProperty('fontStyle', fontStyle);
},
/** */
getFontStyle : function() {
return this.getProperty('fontStyle');
},
/** */
setFontWeight : function(weight) {
this.putProperty('fontWeight', weight);
},
/** */
getFontWeight : function() {
return this.getProperty('fontWeight');
},
/** */
setFontColor : function(color) {
this.putProperty('fontColor', color);
},
/** */
getFontColor : function() {
return this.getProperty('fontColor');
},
/** */
setFontSize : function(size) {
this.putProperty('fontSize', size);
},
/** */
getFontSize : function() {
return this.getProperty('fontSize');
},
/** */
getBorderColor : function() {
return this.getProperty('borderColor');
},
/** */
setBorderColor : function(color) {
this.putProperty('borderColor', color);
},
/** */
getBackgroundColor : function() {
return this.getProperty('backgroundColor');
},
/** */
setBackgroundColor : function(color) {
this.putProperty('backgroundColor', color);
},
/** */
areChildrenShrunken : function() {
var result = this.getProperty('shrunken');
return $defined(result) ? result : false;
},
/**
* @return {Boolean} true if the children nodes are hidden by the shrink option
*/
setChildrenShrunken : function(value) {
this.putProperty('shrunken', value);
},
/**
* @return {Boolean} true
*/
isNodeModel : function() {
return true;
},
/**
* @return {Boolean} true if the node model has a parent assigned to it
*/
isConnected : function() {
return this.getParent() != null;
},
/** @abstract */
append : function(node) {
throw "Unsupported operation";
},
/**
* lets the mindmap handle the connect node operation
* @throws will throw an error if parent is null or undefined
* @see mindplot.model.IMindmap.connect
*/
connectTo : function(parent) {
$assert(parent, "parent can not be null");
var mindmap = this.getMindmap();
mindmap.connect(parent, this);
},
/**
* @param target
* @return target
*/
copyTo : function(target) {
var source = this;
// Copy properties ...
@ -218,7 +279,7 @@ mindplot.model.INodeModel = new Class({
target.putProperty(key, value);
});
// Copy childrens ...
// Copy children ...
var children = this.getChildren();
var tmindmap = target.getMindmap();
@ -231,6 +292,10 @@ mindplot.model.INodeModel = new Class({
return target;
},
/**
* lets parent handle the delete node operation, or, if none defined, calls the mindmap to
* remove the respective branch
*/
deleteNode : function() {
var mindmap = this.getMindmap();
@ -246,30 +311,37 @@ mindplot.model.INodeModel = new Class({
// console.log("After:" + mindmap.inspect());
},
/** @abstract */
getPropertiesKeys : function() {
throw "Unsupported operation";
},
/** @abstract */
putProperty: function(key, value) {
throw "Unsupported operation";
},
/** @abstract */
setParent : function(parent) {
throw "Unsupported operation";
},
/** @abstract */
getChildren : function() {
throw "Unsupported operation";
},
/** @abstract */
getParent : function() {
throw "Unsupported operation";
},
/** @abstract */
clone : function() {
throw "Unsupported operation";
},
/** */
inspect : function() {
var result = '{ type: ' + this.getType() +
' , id: ' + this.getId() +
@ -293,12 +365,16 @@ mindplot.model.INodeModel = new Class({
return result;
},
/** @abstract */
removeChild : function(child) {
throw "Unsupported operation";
}
});
/**
* @enum {String}
*/
mindplot.model.TopicShape =
{
RECTANGLE : 'rectagle',
@ -308,15 +384,28 @@ mindplot.model.TopicShape =
IMAGE : 'image'
};
/**
* @constant
* @type {String}
* @default
*/
mindplot.model.INodeModel.CENTRAL_TOPIC_TYPE = 'CentralTopic';
/**
* @constant
* @type {String}
* @default
*/
mindplot.model.INodeModel.MAIN_TOPIC_TYPE = 'MainTopic';
/**
* @constant
* @type {Number}
* @default
*/
mindplot.model.INodeModel.MAIN_TOPIC_TO_MAIN_TOPIC_DISTANCE = 220;
/**
* @todo: This method must be implemented.
* @todo: This method must be implemented. (unascribed)
*/
mindplot.model.INodeModel._nextUUID = function() {
if (!$defined(mindplot.model.INodeModel._uuid)) {

View File

@ -16,20 +16,33 @@
* limitations under the License.
*/
mindplot.model.IconModel = new Class({
mindplot.model.IconModel = new Class(/** @lends IconModel */{
Extends:mindplot.model.FeatureModel,
/**
* @constructs
* @param attributes
* @extends mindplot.model.FeatureModel
*/
initialize:function (attributes) {
this.parent(mindplot.model.IconModel.FEATURE_TYPE);
this.setIconType(attributes.id);
},
/** @return the icon type id */
getIconType:function () {
return this.getAttribute('id');
},
/** @param {String} iconType the icon type id*/
setIconType:function (iconType) {
$assert(iconType, 'iconType id can not be null');
this.setAttribute('id', iconType);
}
});
/**
* @constant
* @type {String}
* @default
*/
mindplot.model.IconModel.FEATURE_TYPE = "icon";

View File

@ -16,17 +16,27 @@
* limitations under the License.
*/
mindplot.model.LinkModel = new Class({
mindplot.model.LinkModel = new Class(/** @lends LinkModel */{
Extends:mindplot.model.FeatureModel,
/**
* @constructs
* @param attributes
* @extends mindplot.model.FeatureModel
*/
initialize:function (attributes) {
this.parent(mindplot.model.LinkModel.FEATURE_TYPE);
this.setUrl(attributes.url);
},
/** @return {String} the url attribute value */
getUrl:function () {
return this.getAttribute('url');
},
/**
* @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
*/
setUrl:function (url) {
$assert(url, 'url can not be null');
@ -35,8 +45,10 @@ mindplot.model.LinkModel = new Class({
var type = fixedUrl.contains('mailto:') ? 'mail' : 'url';
this.setAttribute('urlType', type);
},
//url format is already checked in LinkEditor.checkUrl
_fixUrl:function (url) {
var result = url;
if (!result.contains('http://') && !result.contains('https://') && !result.contains('mailto://')) {
@ -45,10 +57,19 @@ mindplot.model.LinkModel = new Class({
return result;
},
/**
* @param {String} urlType the url type, either 'mail' or 'url'
* @throws will throw an error if urlType is null or undefined
*/
setUrlType:function (urlType) {
$assert(urlType, 'urlType can not be null');
this.setAttribute('urlType', urlType);
}
});
/**
* @constant
* @type {String}
* @default
*/
mindplot.model.LinkModel.FEATURE_TYPE = 'link';

View File

@ -15,8 +15,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
mindplot.model.Mindmap = new Class({
mindplot.model.Mindmap = new Class(/** @lends Mindmap */{
Extends:mindplot.model.IMindmap,
/**
* @constructs
* @param id
* @param version
* @extends mindplot.model.IMindmap
*/
initialize:function (id, version) {
$assert(id, "Id can not be null");
this._branches = [];
@ -26,31 +33,41 @@ mindplot.model.Mindmap = new Class({
this._id = id;
},
/** */
getDescription:function () {
return this._description;
},
/** */
setDescription:function (value) {
this._description = value;
},
/** */
getId:function () {
return this._id;
},
/** */
setId:function (id) {
this._id = id;
},
/** */
getVersion:function () {
return this._version;
},
/** */
setVersion:function (version) {
this._version = version;
},
/**
* @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
*/
addBranch:function (nodeModel) {
$assert(nodeModel && nodeModel.isNodeModel(), 'Add node must be invoked with model objects');
var branches = this.getBranches();
@ -64,19 +81,28 @@ mindplot.model.Mindmap = new Class({
this._branches.push(nodeModel);
},
/**
* @param nodeModel
*/
removeBranch:function (nodeModel) {
$assert(nodeModel && nodeModel.isNodeModel(), 'Remove node must be invoked with model objects');
return this._branches.erase(nodeModel);
},
/** */
getBranches:function () {
return this._branches;
},
/** */
getRelationships:function () {
return this._relationships;
},
/**
* @param node
* @return {Boolean} true if node already exists
*/
hasAlreadyAdded:function (node) {
var result = false;
@ -90,11 +116,23 @@ mindplot.model.Mindmap = new Class({
}
},
/**
* @param type
* @param id
* @return the node model created
*/
createNode:function (type, id) {
type = !$defined(type) ? mindplot.model.INodeModel.MAIN_TOPIC_TYPE : type;
return new mindplot.model.NodeModel(type, this, id);
},
/**
* @param sourceNodeId
* @param targetNodeId
* @throws will throw an error if source node is null or undefined
* @throws will throw an error if target node is null or undefined
* @return the relationship model created
*/
createRelationship:function (sourceNodeId, targetNodeId) {
$assert($defined(sourceNodeId), 'from node cannot be null');
$assert($defined(targetNodeId), 'to node cannot be null');
@ -102,14 +140,24 @@ mindplot.model.Mindmap = new Class({
return new mindplot.model.RelationshipModel(sourceNodeId, targetNodeId);
},
/**
* @param relationship
*/
addRelationship:function (relationship) {
this._relationships.push(relationship);
},
/**
* @param relationship
*/
deleteRelationship:function (relationship) {
this._relationships.erase(relationship);
},
/**
* @param id
* @return the node with the respective id or null if not in the mindmap
*/
findNodeById:function (id) {
var result = null;
for (var i = 0; i < this._branches.length; i++) {
@ -124,6 +172,10 @@ mindplot.model.Mindmap = new Class({
}
);
/**
* @param mapId
* @return an empty mindmap with central topic only
*/
mindplot.model.Mindmap.buildEmpty = function (mapId) {
var result = new mindplot.model.Mindmap(mapId);
var node = result.createNode(mindplot.model.INodeModel.CENTRAL_TOPIC_TYPE, 0);

View File

@ -16,8 +16,14 @@
* limitations under the License.
*/
mindplot.model.NodeModel = new Class({
mindplot.model.NodeModel = new Class(/** @lends NodeModel */{
Extends:mindplot.model.INodeModel,
/**
* @constructs
* @param {String} type node type
* @param mindmap
* @param id
*/
initialize:function (type, mindmap, id) {
$assert(type, 'Node type can not be null');
$assert(mindmap, 'mindmap can not be null');
@ -32,19 +38,34 @@ mindplot.model.NodeModel = new Class({
this._feature = [];
},
/**
* @param type
* @param attributes
* @return {mindplot.model.FeatureModel} the created feature model
*/
createFeature:function (type, attributes) {
return mindplot.TopicFeature.createModel(type, attributes);
},
/**
* @param feature
* @throws will throw an error if feature is null or undefined
*/
addFeature:function (feature) {
$assert(feature, 'feature can not be null');
this._feature.push(feature);
},
/** */
getFeatures:function () {
return this._feature;
},
/**
* @param feature
* @throws will throw an error if feature is null or undefined
* @throws will throw an error if the feature could not be removed
*/
removeFeature:function (feature) {
$assert(feature, 'feature can not be null');
var size = this._feature.length;
@ -55,6 +76,10 @@ mindplot.model.NodeModel = new Class({
},
/**
* @param {String} type the feature type, e.g. icon or link
* @throws will throw an error if type is null or undefined
*/
findFeatureByType:function (type) {
$assert(type, 'type can not be null');
return this._feature.filter(function (feature) {
@ -62,35 +87,51 @@ mindplot.model.NodeModel = new Class({
});
},
/**
* @param {String} id
* @throws will throw an error if id is null or undefined
* @throws will throw an error if feature could not be found
* @return the feature with the given id
*/
findFeatureById:function (id) {
$assert($defined(id), 'id can not be null');
var result = this._feature.filter(function (feature) {
return feature.getId() == id;
});
$assert(result.length == 1, "Feature could not be found:" + id);
return result[0]
return result[0];
},
/** */
getPropertiesKeys:function () {
return Object.keys(this._properties);
},
/**
* @param key
* @param value
* @throws will throw an error if key is null or undefined
*/
putProperty:function (key, value) {
$defined(key, 'key can not be null');
this._properties[key] = value;
},
/** */
getProperties:function () {
return this._properties;
},
/** */
getProperty:function (key) {
$defined(key, 'key can not be null');
var result = this._properties[key];
return !$defined(result) ? null : result;
},
/**
* @return {mindplot.model.NodeModel} an identical clone of the NodeModel
*/
clone:function () {
var result = new mindplot.model.NodeModel(this.getType(), this._mindmap);
result._children = this._children.map(function (node) {
@ -124,26 +165,37 @@ mindplot.model.NodeModel = new Class({
return result;
},
/**
* @param {mindplot.model.NodeModel} child
* @throws will throw an error if child is null, undefined or not a NodeModel object
*/
append:function (child) {
$assert(child && child.isNodeModel(), 'Only NodeModel can be appended to Mindmap object');
this._children.push(child);
child._parent = this;
},
/**
* @param {mindplot.model.NodeModel} child
* @throws will throw an error if child is null, undefined or not a NodeModel object
*/
removeChild:function (child) {
$assert(child && child.isNodeModel(), 'Only NodeModel can be appended to Mindmap object.');
this._children.erase(child);
child._parent = null;
},
/** */
getChildren:function () {
return this._children;
},
/** */
getParent:function () {
return this._parent;
},
/** */
setParent:function (parent) {
$assert(parent != this, 'The same node can not be parent and child if itself.');
this._parent = parent;
@ -166,6 +218,10 @@ mindplot.model.NodeModel = new Class({
return result;
},
/**
* @id
* @return {mindplot.model.NodeModel} the node with the respective id
*/
findNodeById:function (id) {
var result = null;
if (this.getId() == id) {

View File

@ -16,22 +16,34 @@
* limitations under the License.
*/
mindplot.model.NoteModel = new Class({
mindplot.model.NoteModel = new Class(/** @lends NoteModel */{
Extends:mindplot.model.FeatureModel,
/**
* @constructs
* @param attributes
* @extends mindplot.model.FeatureModel
*/
initialize:function (attributes) {
this.parent(mindplot.model.NoteModel.FEATURE_TYPE);
var noteText = attributes.text ? attributes.text : " ";
this.setText(noteText);
},
/** */
getText:function () {
return this.getAttribute('text');
},
/** */
setText:function (text) {
$assert(text, 'text can not be null');
this.setAttribute('text', text);
}
});
/**
* @constant
* @type {String}
* @default
*/
mindplot.model.NoteModel.FEATURE_TYPE = "note";

View File

@ -15,7 +15,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
mindplot.model.RelationshipModel = new Class({
mindplot.model.RelationshipModel = new Class(/** @lends RelationshipModel */{
Static:{
_nextUUID:function () {
if (!$defined(mindplot.model.RelationshipModel._uuid)) {
@ -26,6 +27,13 @@ mindplot.model.RelationshipModel = new Class({
}
},
/**
* @constructs
* @param sourceTopicId
* @param targetTopicId
* @throws will throw an error if sourceTopicId is null or undefined
* @throws will throw an error if targetTopicId is null or undefined
*/
initialize:function (sourceTopicId, targetTopicId) {
$assert($defined(sourceTopicId), 'from node type can not be null');
$assert($defined(targetTopicId), 'to node type can not be null');
@ -40,59 +48,75 @@ mindplot.model.RelationshipModel = new Class({
this._startArrow = false;
},
/** */
getFromNode:function () {
return this._sourceTargetId;
},
/** */
getToNode:function () {
return this._targetTopicId;
},
/** */
getId:function () {
$assert(this._id, "id is null");
return this._id;
},
/** */
getLineType:function () {
return this._lineType;
},
/** */
setLineType:function (lineType) {
this._lineType = lineType;
},
/** */
getSrcCtrlPoint:function () {
return this._srcCtrlPoint;
},
/** */
setSrcCtrlPoint:function (srcCtrlPoint) {
this._srcCtrlPoint = srcCtrlPoint;
},
/** */
getDestCtrlPoint:function () {
return this._destCtrlPoint;
},
/** */
setDestCtrlPoint:function (destCtrlPoint) {
this._destCtrlPoint = destCtrlPoint;
},
/** */
getEndArrow:function () {
return this._endArrow;
},
/** */
setEndArrow:function (endArrow) {
this._endArrow = endArrow;
},
/** */
getStartArrow:function () {
return this._startArrow;
},
/** */
setStartArrow:function (startArrow) {
this._startArrow = startArrow;
},
/**
* @return a clone of the relationship model
*/
clone:function () {
var result = new mindplot.model.RelationshipModel(this._sourceTargetId, this._targetTopicId);
result._id = this._id;
@ -104,6 +128,9 @@ mindplot.model.RelationshipModel = new Class({
return result;
},
/**
* @return {String} textual information about the relationship's source and target node
*/
inspect:function () {
return '(fromNode:' + this.getFromNode().getId() + ' , toNode: ' + this.getToNode().getId() + ')';
}

View File

@ -15,6 +15,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Enum for wisemap version names
* @enum {String}
*/
mindplot.persistence.ModelCodeName = {
BETA : "beta",
PELA : "pela",

View File

@ -15,18 +15,37 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @class mindplot.persistence.XMLSerializerFactory
*/
mindplot.persistence.XMLSerializerFactory = {};
/**
* @param {mindplot.model.IMindmap} mindmap
* @return {mindplot.persistence.XMLSerializer_Beta|mindplot.persistence.XMLSerializer_Pela|
* mindplot.persistence.XMLSerializer_Tango} serializer corresponding to the mindmap's version
*/
mindplot.persistence.XMLSerializerFactory.getSerializerFromMindmap = function(mindmap) {
return mindplot.persistence.XMLSerializerFactory.getSerializer(mindmap.getVersion());
};
/**
* @param domDocument
* @return serializer corresponding to the mindmap's version
*/
mindplot.persistence.XMLSerializerFactory.getSerializerFromDocument = function(domDocument) {
var rootElem = domDocument.documentElement;
return mindplot.persistence.XMLSerializerFactory.getSerializer(rootElem.getAttribute("version"))
};
/**
* retrieves the serializer for the mindmap's version and migrates to the current version,
* e.g. for a Beta mindmap and current version Tango:
* serializer = new Pela2TangoMigrator(new Beta2PelaMigrator(new XMLSerializer_Beta()))
* @param {String} version the version name
* @return serializer
*/
mindplot.persistence.XMLSerializerFactory.getSerializer = function(version) {
if (!$defined(version)) {
version = mindplot.persistence.ModelCodeName.BETA;

View File

@ -16,8 +16,16 @@
* limitations under the License.
*/
mindplot.persistence.XMLSerializer_Pela = new Class({
/**
* @class
*/
mindplot.persistence.XMLSerializer_Pela = new Class(/** @lends XMLSerializer_Pela */{
/**
* @param mindmap
* @throws will throw an error if mindmap is null or undefined
* @return the created XML document (using the cross-browser implementation in core)
*/
toXML: function (mindmap) {
$assert(mindmap, "Can not save a null mindmap");
@ -203,6 +211,14 @@ mindplot.persistence.XMLSerializer_Pela = new Class({
return result;
},
/**
* @param dom
* @param mapId
* @throws will throw an error if dom is null or undefined
* @throws will throw an error if mapId is null or undefined
* @throws will throw an error if the document element is not consistent with a wisemap's root
* element
*/
loadFromDom: function (dom, mapId) {
$assert(dom, "dom can not be null");
$assert(mapId, "mapId can not be null");
@ -436,8 +452,9 @@ mindplot.persistence.XMLSerializer_Pela = new Class({
model.setEndArrow('false');
model.setStartArrow('true');
return model;
}
/*
},
/**
* This method ensures that the output String has only
* valid XML unicode characters as specified by the
* XML 1.0 standard. For reference, please see
@ -447,7 +464,7 @@ mindplot.persistence.XMLSerializer_Pela = new Class({
*
* @param in The String whose non-valid characters we want to remove.
* @return The in String, stripped of non-valid characters.
*/,
*/
rmXmlInv: function (str) {
if (str == null || str == undefined)
@ -469,4 +486,10 @@ mindplot.persistence.XMLSerializer_Pela = new Class({
}
});
/**
* a wisemap's root element tag name
* @constant
* @type {String}
* @default
*/
mindplot.persistence.XMLSerializer_Pela.MAP_ROOT_NODE = 'map';

View File

@ -16,6 +16,12 @@
* limitations under the License.
*/
/**
* This serializer works exactly the same way as for the former version Pela
* {@link mindplot.persistence.XMLSerializer_Pela}
* @class
* @extends mindplot.persistence.XMLSerializer_Pela
*/
mindplot.persistence.XMLSerializer_Tango = new Class({
Extends: mindplot.persistence.XMLSerializer_Pela
});

View File

@ -17,13 +17,20 @@
*/
//FIXME: this Class should be reimplemented
mindplot.util.FadeEffect = new Class({
mindplot.util.FadeEffect = new Class(/** @lends FadeEffect */{
Extends: mindplot.Events,
/**
* @extends mindplot.Events
* @constructs
* @param elements
* @param isVisible
*/
initialize: function(elements, isVisible) {
this._isVisible = isVisible;
this._element = elements;
},
/** */
start: function(){
var visible = this._isVisible;
_.each(this._element, function(elem) {

View File

@ -16,9 +16,15 @@
* limitations under the License.
*/
mindplot.widget.LinkEditor = new Class({
mindplot.widget.LinkEditor = new Class(/** @lends LinkEditor */{
Extends:BootstrapDialog,
/**
* @constructs
* @param model
* @throws will throw an error if model is null or undefined
* @extends BootstrapDialog
*/
initialize:function (model) {
$assert(model, "model can not be null");
this._model = model;
@ -101,11 +107,20 @@ mindplot.widget.LinkEditor = new Class({
return result;
},
/**
* checks whether the input is a valid url
* @return {Boolean} true if the url is valid
*/
checkURL: function(url){
var regex = /^(http|https|ftp):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/i;
return(regex.test(url));
},
/**
* overrides abstract parent method
* triggered when the user clicks the accept button - submits the url input
* @param event
*/
onAcceptClick: function(event) {
this.formSubmitted = false;
$("#linkFormId").trigger('submit');
@ -114,10 +129,18 @@ mindplot.widget.LinkEditor = new Class({
}
},
/**
* overrides parent method
* sets the url input on focus
*/
onDialogShown: function() {
$(this).find('#inputUrl').focus();
},
/**
* overrides abstract parent method
* triggered when the user clicks the remove button - deletes the link
*/
onRemoveClick: function(event) {
event.data.model.setValue(null);
event.data.dialog.close();