mirror of
https://bitbucket.org/wisemapping/wisemapping-open-source.git
synced 2024-12-25 04:33:50 +01:00
Merge branch 'develop'
This commit is contained in:
commit
70fba42683
1
.gitignore
vendored
1
.gitignore
vendored
@ -11,3 +11,4 @@ wisemapping.log*
|
||||
.DS_Store
|
||||
target
|
||||
.idea
|
||||
wise-webapp/src/main/webapp/react/*
|
||||
|
1
Procfile
1
Procfile
@ -1 +0,0 @@
|
||||
web: java $JAVA_OPTS -Dspring.profiles.active=heroku -jar wise-webapp/target/dependency/jetty-runner.jar --port $PORT wise-webapp/target/*.war
|
47
README.md
47
README.md
@ -1,6 +1,7 @@
|
||||
# Project Information
|
||||
# Overview
|
||||
|
||||
The goal of this project is to provide a high quality product that can be deployed by educational and academic institutions, private and public companies and anyone who needs to have a mindmapping application. WiseMapping is based on the same code source supporting WiseMapping.com. More info: www.wisemapping.org
|
||||
Wise Mapping is the web mind mapping open source tool that leverages the power of Mind Maps mixing open standards technologies such as SVG and React.
|
||||
WiseMapping is based on the same code product supporting [http://www.wisemapping.com].
|
||||
|
||||
## Compiling and Running
|
||||
|
||||
@ -8,67 +9,63 @@ The goal of this project is to provide a high quality product that can be deploy
|
||||
|
||||
The following products must be installed:
|
||||
|
||||
* Java Development Kit 8 or higher ([http://www.oracle.com/technetwork/java/javase/downloads/index.html])
|
||||
* OpenJDK 11 or higher
|
||||
* Maven 3.x or higher ([http://maven.apache.org/])
|
||||
|
||||
### Compiling
|
||||
|
||||
WiseMapping uses Maven as packaging and project management. It's composed of 5 maven sub-modules:
|
||||
|
||||
* core-js: Utilities JavaScript classes
|
||||
* web2d: JavaScript 2D SVG abstraction library used by the mind map editor
|
||||
* mindplot: JavaScript mindmap designer core
|
||||
* wise-editor: Mindmap Editor standalone distribution
|
||||
* wise-ui: React font-end fetcher
|
||||
* wise-webapp: J2EE web application
|
||||
|
||||
The full compilation of the project can be performed executing within <project-dir>:
|
||||
|
||||
`mvn package`
|
||||
`mvn clean install`
|
||||
|
||||
Once this command is execute, the file <project-dir>/wise-webapp/target/wisemapping*.war will be generated.
|
||||
Once this command is executed, the file <project-dir>/wise-webapp/target/wisemapping*.war will be generated.
|
||||
|
||||
### Testing
|
||||
### Local Development
|
||||
The previously generated war can be deployed locally executing within the directory <project-dir>/wise-webapp the following command:
|
||||
|
||||
`cd wise-webapp;mvn jetty:run-war`
|
||||
|
||||
This will start the application on the URL: [http://localhost:8080/] using file based database..
|
||||
This will start the application on the URL: [http://localhost:8080/] using file based database.
|
||||
|
||||
User: test@wisemapping.org
|
||||
Password: test
|
||||
|
||||
## Running the JS only version
|
||||
### Local Development + UI Integration
|
||||
|
||||
Start by creating the .zip file:
|
||||
In order to reduce the life-cycle to develop UI backend testing, you can do the following hack:
|
||||
|
||||
`mvn assembly:assembly -Dmaven.test.skip=true`
|
||||
* Clone [wisemapping-open-source](https://bitbucket.org/wisemapping/wisemapping-open-source/) and [wisemapping-frontend](https://bitbucket.org/wisemapping/wisemapping-frontend/) at the same top level directory
|
||||
* Compile `wisemapping-frontend`. Details for compilation can be found in the `wisemapping-frontend` readme.
|
||||
* Compile `wisemapping-open-source`
|
||||
|
||||
To test the javascript frontend you then do:
|
||||
A quick and dirty solution to share changes in the UI is to manually compile the dist. This will make the loader file available without the need to publish:
|
||||
|
||||
ruby -rwebrick -e 'WEBrick::HTTPServer.new(:Port=>8000,:DocumentRoot=>".").start'
|
||||
|
||||
Now open a browser using the URL http://localhost:8000/wise-editor/src/main/webapp/
|
||||
|
||||
## Maintenance
|
||||
`cp -r wisemapping-frontend/packages/mindplot/dist/* wisemapping-open-source/wise-ui/target/wisemapping-mindplot/package/dist`
|
||||
|
||||
|
||||
### Compiling and running with docker-compose
|
||||
|
||||
Check out the [docker section](./docker/README.
|
||||
|
||||
## Members
|
||||
|
||||
### Founders
|
||||
|
||||
* Pablo Luna <pveiga@wisemapping.com>
|
||||
* Paulo Veiga <pablo@wisemapping.com>
|
||||
* Paulo Veiga <pveiga@wisemapping.com>
|
||||
* Pablo Luna <pablo@wisemapping.com>
|
||||
|
||||
### Individual Controbutors
|
||||
### Individual Contributors
|
||||
|
||||
* Ezequiel Bergamaschi <ezequielbergamaschi@gmail.com>
|
||||
* Claudio Barril <claudiobarril@gmail.com>
|
||||
|
||||
### Past Individual Contributors
|
||||
|
||||
* Ignacio Manzano
|
||||
* Nicolas Damonte
|
||||
|
||||
## License
|
||||
|
||||
|
@ -8,20 +8,32 @@
|
||||
image: maven:3.6.3
|
||||
|
||||
pipelines:
|
||||
default:
|
||||
- parallel:
|
||||
branches:
|
||||
'{master,develop}':
|
||||
- step:
|
||||
name: Build and Test
|
||||
caches:
|
||||
- node
|
||||
- maven
|
||||
- docker
|
||||
script:
|
||||
- mvn -B verify --file pom.xml install
|
||||
# Compile sources ...
|
||||
- curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.36.0/install.sh | bash
|
||||
- . $HOME/.nvm/nvm.sh && nvm install node
|
||||
- mvn -B verify --file pom.xml
|
||||
# Publish to docker repo ...
|
||||
- docker login --username $DOCKER_USERNAME --password $DOCKER_PASSWORD
|
||||
- docker build -t wisemapping/wisemapping:latest -f distribution/Dockerfile wise-webapp/target/
|
||||
- docker push wisemapping/wisemapping:latest
|
||||
after-script:
|
||||
# Collect checkstyle results, if any, and convert to Bitbucket Code Insights.
|
||||
- pipe: atlassian/checkstyle-report:0.2.0
|
||||
# Collect checkstyle results, if any, and convert to Bitbucket Code Insights.
|
||||
- pipe: atlassian/checkstyle-report:0.3.0
|
||||
services:
|
||||
- docker
|
||||
- step:
|
||||
name: Security Scan
|
||||
script:
|
||||
# Run a security scan for sensitive data.
|
||||
# See more security tools at https://bitbucket.org/product/features/pipelines/integrations?&category=security
|
||||
- pipe: atlassian/git-secrets-scan:0.4.3
|
||||
- pipe: atlassian/git-secrets-scan:0.5.1
|
||||
|
||||
|
@ -1,94 +0,0 @@
|
||||
<project>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>core-js</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Core JavaScript Utils Libraries</name>
|
||||
|
||||
<parent>
|
||||
<groupId>org.wisemapping</groupId>
|
||||
<artifactId>wisemapping</artifactId>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
<version>5.0.1</version>
|
||||
</parent>
|
||||
<scm>
|
||||
<developerConnection>scm:git:git@bitbucket.org:wisemapping/wisemapping-open-source.git</developerConnection>
|
||||
</scm>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>merge-js-resources</id>
|
||||
<phase>generate-resources</phase>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<tasks>
|
||||
<mkdir dir="${basedir}/target/classes"/>
|
||||
</tasks>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-release-plugin</artifactId>
|
||||
<version>2.5</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.github.searls</groupId>
|
||||
<artifactId>jasmine-maven-plugin</artifactId>
|
||||
<version>1.3.1.5</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<sourceIncludes>
|
||||
<include>Functions.js</include>
|
||||
</sourceIncludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>net.alchim31.maven</groupId>
|
||||
<artifactId>yuicompressor-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>generate-resources</phase>
|
||||
<goals>
|
||||
<goal>compress</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sourceDirectory>src/main/javascript/</sourceDirectory>
|
||||
<outputDirectory>target/tmp/</outputDirectory>
|
||||
<aggregations>
|
||||
<aggregation>
|
||||
<output>${basedir}/target/classes/core.js</output>
|
||||
<includes>
|
||||
<include>${basedir}/target/tmp/header-min.js</include>
|
||||
<include>${basedir}/target/tmp/Functions-min.js</include>
|
||||
<include>${basedir}/target/tmp/Utils-min.js</include>
|
||||
<include>${basedir}/../mindplot/src/main/javascript/Options.js</include>
|
||||
<include>${basedir}/../mindplot/src/main/javascript/libraries/bootstrap/BootstrapDialog.js</include>
|
||||
<include>${basedir}/../mindplot/src/main/javascript/libraries/bootstrap/BootstrapDialog.Request.js</include>
|
||||
</includes>
|
||||
</aggregation>
|
||||
</aggregations>
|
||||
<nomunge>true</nomunge>
|
||||
<jswarn>false</jswarn>
|
||||
<force>true</force>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
Function: $defined
|
||||
Returns true if the passed in value/object is defined, that means is not null or undefined.
|
||||
|
||||
Arguments:
|
||||
obj - object to inspect
|
||||
*/
|
||||
|
||||
$defined = function (obj) {
|
||||
return (obj != undefined);
|
||||
};
|
||||
|
||||
|
||||
$assert = function (assert, message) {
|
||||
if (!$defined(assert) || !assert) {
|
||||
logStackTrace();
|
||||
console.log(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
};
|
||||
|
||||
Math.sign = function (value) {
|
||||
return (value >= 0) ? 1 : -1;
|
||||
};
|
||||
|
||||
function logStackTrace(exception) {
|
||||
|
||||
if (!$defined(exception)) {
|
||||
try {
|
||||
throw Error("Unexpected Exception");
|
||||
} catch (e) {
|
||||
exception = e;
|
||||
}
|
||||
}
|
||||
var result = "";
|
||||
if (exception.stack) { //Firefox and Chrome...
|
||||
result = exception.stack;
|
||||
}
|
||||
else if (window.opera && exception.message) { //Opera
|
||||
result = exception.message;
|
||||
} else { //IE and Safari
|
||||
result = exception.sourceURL + ': ' + exception.line + "\n\n";
|
||||
|
||||
var currentFunction = arguments.callee.caller;
|
||||
while (currentFunction) {
|
||||
var fn = currentFunction.toString();
|
||||
result = result + "\n" + fn;
|
||||
currentFunction = currentFunction.caller;
|
||||
}
|
||||
}
|
||||
window.errorStack = result;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Support for Windows ...
|
||||
if (!window.console) {
|
||||
console = {
|
||||
log:function (e) {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
core.Utils = {
|
||||
|
||||
};
|
||||
|
||||
|
||||
core.Utils.innerXML = function (node) {
|
||||
// summary:
|
||||
// Implementation of MS's innerXML function.
|
||||
if ($defined(node.innerXML)) {
|
||||
return node.innerXML;
|
||||
// string
|
||||
} else if ($defined(node.xml)) {
|
||||
return node.xml;
|
||||
// string
|
||||
} else if ($defined(XMLSerializer)) {
|
||||
return (new XMLSerializer()).serializeToString(node);
|
||||
// string
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Cross-browser implementation of creating an XML document object.
|
||||
*/
|
||||
core.Utils.createDocument = function () {
|
||||
var doc = null;
|
||||
if ($defined(window.ActiveXObject)) {
|
||||
//http://blogs.msdn.com/b/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx
|
||||
var progIDs = [ 'Msxml2.DOMDocument.6.0', 'Msxml2.DOMDocument.3.0'];
|
||||
for (var i = 0; i < progIDs.length; i++) {
|
||||
try {
|
||||
doc = new ActiveXObject(progIDs[i]);
|
||||
break;
|
||||
}
|
||||
catch (ex) {
|
||||
}
|
||||
}
|
||||
} else if (window.document.implementation && window.document.implementation.createDocument) {
|
||||
doc = window.document.implementation.createDocument("", "", null);
|
||||
}
|
||||
$assert(doc, "Parser could not be instantiated");
|
||||
|
||||
return doc;
|
||||
};
|
@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
var core = {};
|
@ -1,10 +0,0 @@
|
||||
describe("Functions suite test", function() {
|
||||
it("$defined() test spec", function() {
|
||||
var testVariable = undefined;
|
||||
expect($defined(testVariable)).toBe(false);
|
||||
testVariable = 1;
|
||||
expect($defined(testVariable)).toBe(true);
|
||||
testVariable = null;
|
||||
expect($defined(testVariable)).toBe(false);
|
||||
});
|
||||
});
|
@ -1,47 +1,27 @@
|
||||
# Dockerizing WiseMapping: Dockerfile for building WiseMapping images
|
||||
# Based on ubuntu:latest, installs WiseMapping (http://ww.wisemapping.org)
|
||||
|
||||
FROM ubuntu:latest
|
||||
MAINTAINER Paulo Gustavo Veiga <pveiga@wisemapping.com>
|
||||
# Based info setup ...
|
||||
FROM tomcat:9.0-jdk17-openjdk
|
||||
LABEL maintainer="Paulo Gustavo Veiga <pveiga@wisemapping.com>"
|
||||
|
||||
ENV DEBIAN_FRONTEND noninteractive
|
||||
ENV MYSQL_ROOT_PASSWORD password
|
||||
ENV WISE_VERSION 4.0.2
|
||||
# Build variables ...
|
||||
ARG WEBAPP_TARGET_DIR="/usr/local/tomcat/webapps/ROOT"
|
||||
ARG DB_BASE_DIR="/var/lib/wisemapping"
|
||||
|
||||
# Install utilities
|
||||
RUN apt-get install -y zip
|
||||
# Defautl ENV configurations ...
|
||||
ENV JAVA_OPTS="-XX:+PrintFlagsFinal -XX:InitialRAMPercentage=30 -XX:MaxRAMPercentage=80"
|
||||
ENV database.base.url=${DB_BASE_DIR}
|
||||
|
||||
# Prepare distribution
|
||||
COPY target/wisemapping-v${WISE_VERSION}.zip .
|
||||
RUN unzip wisemapping-v${WISE_VERSION}.zip
|
||||
# Copy wisemapping distribution ...
|
||||
COPY wisemapping.war /tmp
|
||||
RUN mkdir ${WEBAPP_TARGET_DIR}
|
||||
RUN cd ${WEBAPP_TARGET_DIR} && jar -xvf /tmp/wisemapping.war
|
||||
RUN rm /tmp/wisemapping.war
|
||||
|
||||
# Install MySQL
|
||||
RUN echo mysql-server mysql-server/root_password password ${MYSQL_ROOT_PASSWORD} | debconf-set-selections;\
|
||||
echo mysql-server mysql-server/root_password_again password ${MYSQL_ROOT_PASSWORD} | debconf-set-selections;\
|
||||
apt-get install -y mysql-server
|
||||
# Change logger to
|
||||
RUN cp ${WEBAPP_TARGET_DIR}/WEB-INF/classes/log4j-stdout.properties ${WEBAPP_TARGET_DIR}/WEB-INF/classes/log4j.properties
|
||||
|
||||
RUN service mysql start && \
|
||||
mysql -uroot -p${MYSQL_ROOT_PASSWORD} < /wisemapping-v${WISE_VERSION}/config/database/mysql/create-database.sql && \
|
||||
mysql -uwisemapping -Dwisemapping -ppassword < /wisemapping-v${WISE_VERSION}/config/database/mysql/create-schemas.sql && \
|
||||
mysql -uwisemapping -Dwisemapping -ppassword < /wisemapping-v${WISE_VERSION}/config/database/mysql/apopulate-schemas.sql
|
||||
|
||||
# Install Java 8
|
||||
RUN apt-get install -y software-properties-common && \
|
||||
add-apt-repository ppa:webupd8team/java && \
|
||||
apt-get update
|
||||
|
||||
RUN echo oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | debconf-set-selections;\
|
||||
echo oracle-java8-installer shared/accepted-oracle-license-v1-1 seen true | debconf-set-selections;\
|
||||
sudo apt-get install -y oracle-java8-installer
|
||||
|
||||
# Configure instance
|
||||
COPY docker-conf/app.properties wisemapping-v4.0.1/webapps/wisemapping/WEB-INF/app.properties
|
||||
|
||||
# Clean up
|
||||
RUN apt-get clean
|
||||
RUN rm wisemapping-v${WISE_VERSION}.zip
|
||||
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
CMD "sh" "-c" "service mysql start;cd wisemapping-v${WISE_VERSION};./start.sh"
|
||||
# Copy default HSQL DB for testing ...
|
||||
RUN mkdir -p ${DB_BASE_DIR}/db
|
||||
COPY db/ ${DB_BASE_DIR}/db
|
||||
|
47
distribution/README.md
Normal file
47
distribution/README.md
Normal file
@ -0,0 +1,47 @@
|
||||
# What is WiseMapping ?
|
||||
|
||||
Wise Mapping is the web mind mapping open source tool that leverages the power of Mind Maps mixing open standards technologies such as SVG and React.
|
||||
WiseMapping is based on the same code product supporting [http://www.wisemapping.com].
|
||||
|
||||
# How to use this image.
|
||||
|
||||
There are multiple ways to run WiseMapping depending on your database configuration preference
|
||||
|
||||
## Option 1: Running HSQL within the image storage
|
||||
|
||||
> $ docker run -it --rm -p 8080:8080 veigap/wisemapping:latest>
|
||||
|
||||
Then, open your browser at `http://localhost:8888`. A default user is available for testing `test@wisemapping.com` and password `test`.
|
||||
|
||||
***This option, all changes will be lost once the image is stopped. Use it for testing only***
|
||||
|
||||
## Option 2: Running HSQL with mounted directory
|
||||
|
||||
> $ docker run -it --rm -p 8080:8080 veigap/wisemapping:latest
|
||||
|
||||
## Option 3: External MySQL/PostgreSQL
|
||||
|
||||
### Setup database
|
||||
|
||||
Depending on the database your want to configure, you can create initialization scripts [here](https://bitbucket.org/wisemapping/wisemapping-open-source/src/develop/config/database/)
|
||||
|
||||
### Configure application properties
|
||||
|
||||
The next step is configure the WiseMapping for the database and credentials.
|
||||
Download `app.properties` configuration file and configure the required sections:
|
||||
|
||||
> $ curl https://bitbucket.org/wisemapping/wisemapping-open-source/raw/644b7078d790220c7844b732a83d45495f11d64e/wise-webapp/src/main/webapp/WEB-INF/app.properties
|
||||
|
||||
### Starting the application
|
||||
|
||||
Run the application mounting your previously configured `app.properties`
|
||||
|
||||
> $ docker run --mount type=bind,source=your-file-path/app.properties,target=/usr/local/tomcat/webapps/ROOT/WEB-INF/app.properties -it --rm -p 8080:8080 veigap/wisemapping:latest
|
||||
|
||||
# Advanced configuration
|
||||
|
||||
## Increase Tomcat memory
|
||||
> docker run\
|
||||
> --mount type=bind,source<your-file-path/app.properties,target=/usr/local/tomcat/webapps/ROOT/classes/app.properties
|
||||
> -m 1.5GB -e JAVA_OPTS=" -XX:+PrintFlagsFinal -XX:InitialRAMPercentage=30 -XX:MaxRAMPercentage=80"
|
||||
> -it --rm -p 8888:8080 veigap/wisemapping:latest
|
@ -1,36 +0,0 @@
|
||||
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
|
||||
<id>editor</id>
|
||||
<formats>
|
||||
<format>zip</format>
|
||||
</formats>
|
||||
<files>
|
||||
<file>
|
||||
<source>core-js/target/classes/core.js</source>
|
||||
<outputDirectory>/js</outputDirectory>
|
||||
</file>
|
||||
<file>
|
||||
<source>mindplot/target/classes/mindplot-min.js</source>
|
||||
<outputDirectory>/js</outputDirectory>
|
||||
</file>
|
||||
</files>
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<outputDirectory>/</outputDirectory>
|
||||
<directory>wise-editor/src/main/webapp</directory>
|
||||
<includes>
|
||||
<include>css/**/*</include>
|
||||
<include>images/**/*</include>
|
||||
<include>icons/**/*</include>
|
||||
<include>js/editor.js</include>
|
||||
<include>js/less*.js</include>
|
||||
<include>js/mootools*.js</include>
|
||||
<include>html/editor.html</include>
|
||||
<include>html/*</include>
|
||||
<include>samples/*</include>
|
||||
<include>index.html</include>
|
||||
</includes>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
</assembly>
|
7
distribution/build-image.sh
Executable file
7
distribution/build-image.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -o
|
||||
set -u
|
||||
|
||||
mvn -f ../pom.xml clean package
|
||||
docker build -t wisemapping/wisemapping:latest -f ./Dockerfile ../wise-webapp/target/
|
@ -1,160 +0,0 @@
|
||||
##################################################################################
|
||||
# Database Configuration
|
||||
##################################################################################
|
||||
|
||||
# MariaDB configuration properties
|
||||
database.url=jdbc:mariadb://localhost/wisemapping?useUnicode=yes&characterEncoding=UTF-8
|
||||
database.driver=org.mariadb.jdbc.Driver
|
||||
database.hibernate.dialect=org.hibernate.dialect.MariaDBDialect
|
||||
database.username=wisemapping
|
||||
database.password=mappingwise
|
||||
database.validation.enabled=true
|
||||
database.validation.query=SELECT 1
|
||||
|
||||
# MySQL 5.X configuration properties
|
||||
#database.url=jdbc:mysql://localhost/wisemapping?useUnicode=yes&characterEncoding=UTF-8
|
||||
#database.driver=com.mysql.jdbc.Driver
|
||||
#database.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
|
||||
#database.username=wisemapping
|
||||
#database.password=password
|
||||
#database.validation.enabled=true
|
||||
#database.validation.query=SELECT 1
|
||||
|
||||
|
||||
## PostgreSQL configuration properties
|
||||
#database.url=jdbc:mariadb://localhost:3306/wisemapping
|
||||
#database.driver=org.mariadb.jdbc.Driver
|
||||
#database.hibernate.dialect=org.hibernate.dialect.MariaDBDialect
|
||||
#database.username=wisemapping
|
||||
#database.password=password
|
||||
#database.validation.query=
|
||||
#database.validation.enabled=false
|
||||
|
||||
|
||||
# HSQL Configuration properties
|
||||
#database.url=jdbc:hsqldb:file:${database.base.url}/db/wisemapping
|
||||
#database.driver=org.hsqldb.jdbc.JDBCDriver
|
||||
#database.hibernate.dialect=org.hibernate.dialect.HSQLDialect
|
||||
#database.username=sa
|
||||
#database.password=
|
||||
#database.validation.enabled=false
|
||||
#database.validation.query=
|
||||
|
||||
##################################################################################
|
||||
# Mail configuration. Must be configured to enable user registration confirmation.
|
||||
##################################################################################
|
||||
|
||||
#------------------------
|
||||
# Plain SMTP Server Configuration
|
||||
#------------------------
|
||||
mail.smtp.port=25
|
||||
mail.smtp.host=localhost
|
||||
mail.username=root
|
||||
mail.password=
|
||||
mail.smtp.auth=false
|
||||
mail.smtp.starttls.enable=false
|
||||
mail.smtp.quitwait=false
|
||||
|
||||
#------------------------
|
||||
# GMAIL SMTP Configuration
|
||||
#------------------------
|
||||
#mail.smtp.port=587
|
||||
#mail.smtp.host=smtp.gmail.com
|
||||
#mail.username=<gmail-user-account>
|
||||
#mail.password=<gmail-password>
|
||||
#mail.smtp.auth=true
|
||||
#mail.smtp.starttls.enable=true
|
||||
#mail.smtp.quitwait=false
|
||||
|
||||
#------------------------
|
||||
# Emails configuration
|
||||
#------------------------
|
||||
|
||||
# Required: "from" email account that will appear in the emails sent from the sender.
|
||||
mail.serverSendEmail=root@localhost
|
||||
|
||||
# Optional: Support account that the users could use to contact you. This address will appear in emails and in some places in the site.
|
||||
mail.supportEmail=root@localhost
|
||||
|
||||
# Optional: Unexpected errors will be reported to this address.
|
||||
mail.errorReporterEmail=
|
||||
|
||||
##################################################################################
|
||||
# Users Registration Configuration
|
||||
##################################################################################
|
||||
|
||||
# Enable captcha confirmation
|
||||
google.recaptcha2.enabled = true
|
||||
|
||||
# ReCaptcha is the default captcha. Public and private keys are required.
|
||||
# More Info: http://www.google.com/recaptcha .
|
||||
google.recaptcha2.siteKey = 6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
|
||||
google.recaptcha2.secretKey = 6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe
|
||||
|
||||
##################################################################################
|
||||
# Site configuration
|
||||
##################################################################################
|
||||
|
||||
# Site administration user. This user will have special permissions for operations such as removing users, set password
|
||||
# etc.
|
||||
admin.user = admin@wisemapping.org
|
||||
|
||||
# Base URL where WiseMapping is deployed. By default, It will be automatically inferred.
|
||||
# If you are planning to put wisemapping behind an Apache using an Apache Proxy setup, you must enable this property.
|
||||
#site.baseurl = http://example.com:8080/wisemapping
|
||||
|
||||
|
||||
# Site Homepage URL. This will be used as URL for homepage location.
|
||||
site.homepage = c/home
|
||||
|
||||
##################################################################################
|
||||
# Google Analytics Settings
|
||||
##################################################################################
|
||||
google.analytics.enabled=false
|
||||
google.analytics.account=UA-XXXX
|
||||
|
||||
##################################################################################
|
||||
# Google Ads enable
|
||||
##################################################################################
|
||||
google.ads.enabled=false
|
||||
|
||||
#######################################################################################
|
||||
# Authentication Configuration Section
|
||||
#######################################################################################
|
||||
|
||||
# Two type of security are supported:
|
||||
# - db: User are stored in the database. Registration is required in advance.
|
||||
# - ldap: Authentication takes place using a LDAP. In this case, security.ldap.* must be configured.
|
||||
security.type=db
|
||||
|
||||
# LDAP Configuration properties.
|
||||
security.ldap.server=ldap://localhost:389
|
||||
|
||||
# If anonymous password is required, change the wisemapping-security-ldap.xml removing the
|
||||
security.ldap.server.user=cn=pveiga,dc=wisemapping,dc=com
|
||||
security.ldap.server.password=password
|
||||
|
||||
security.ldap.basedn=dc=wisemapping,dc=com
|
||||
|
||||
|
||||
# This will be concatenated as part of the DN. In this case, I will be "ou=people".
|
||||
# In case this need to be changed, modify the wisemapping-security-ldap.xml.
|
||||
security.ldap.subDn=ou=people
|
||||
|
||||
# Attribute used as authentication login (Eg: in this case, the user email will be used)
|
||||
security.ldap.auth.attribute=mail
|
||||
|
||||
security.ldap.lastName.attribute=sn
|
||||
security.ldap.firstName.attribute=givenName
|
||||
|
||||
# Enable OpenId Authentication.
|
||||
security.openid.enabled=false
|
||||
|
||||
# REST Documentation
|
||||
#
|
||||
# This properties are used for REST API Documentation( http://localhost:8080/wisemapping/doc/rest/index.html)
|
||||
# Change the URL for proper documentation console setup.
|
||||
documentation.services.basePath=http://localhost:8080/service
|
||||
documentation.services.version=3.0.1
|
||||
|
||||
|
10
distribution/mysql-init/0001create-database.sql
Normal file
10
distribution/mysql-init/0001create-database.sql
Normal file
@ -0,0 +1,10 @@
|
||||
#
|
||||
# Command: mysql -u root -p < create_database.sql
|
||||
#
|
||||
DROP DATABASE IF EXISTS wisemapping;
|
||||
|
||||
CREATE DATABASE IF NOT EXISTS wisemapping
|
||||
CHARACTER SET = 'utf8'
|
||||
COLLATE = 'utf8_unicode_ci';
|
||||
GRANT ALL ON wisemapping.* TO 'wisemapping'@'localhost';
|
||||
SET PASSWORD FOR 'wisemapping'@'localhost' = PASSWORD('password');
|
137
distribution/mysql-init/0002create-schemas.sql
Normal file
137
distribution/mysql-init/0002create-schemas.sql
Normal file
@ -0,0 +1,137 @@
|
||||
#
|
||||
# Command: mysql -u root -p < create_schemas.sql
|
||||
#
|
||||
|
||||
USE wisemapping;
|
||||
|
||||
CREATE TABLE COLLABORATOR (
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
email VARCHAR(255)
|
||||
CHARACTER SET utf8 NOT NULL UNIQUE,
|
||||
creation_date DATE
|
||||
)
|
||||
CHARACTER SET utf8;
|
||||
|
||||
CREATE TABLE USER (
|
||||
colaborator_id INTEGER NOT NULL PRIMARY KEY,
|
||||
authentication_type CHAR(1)
|
||||
CHARACTER SET utf8 NOT NULL,
|
||||
authenticator_uri VARCHAR(255)
|
||||
CHARACTER SET utf8,
|
||||
firstname VARCHAR(255) CHARACTER SET utf8 NOT NULL,
|
||||
lastname VARCHAR(255) CHARACTER SET utf8 NOT NULL,
|
||||
password VARCHAR(255) CHARACTER SET utf8 NOT NULL,
|
||||
activation_code BIGINT(20) NOT NULL,
|
||||
activation_date DATE,
|
||||
allow_send_email CHAR(1) CHARACTER SET utf8 NOT NULL DEFAULT 0,
|
||||
locale VARCHAR(5),
|
||||
FOREIGN KEY (colaborator_id) REFERENCES COLLABORATOR (id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION
|
||||
)
|
||||
CHARACTER SET utf8;
|
||||
|
||||
CREATE TABLE MINDMAP (
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
title VARCHAR(255)
|
||||
CHARACTER SET utf8 NOT NULL,
|
||||
description VARCHAR(255)
|
||||
CHARACTER SET utf8 NOT NULL,
|
||||
xml MEDIUMBLOB NOT NULL,
|
||||
public BOOL NOT NULL DEFAULT 0,
|
||||
creation_date DATETIME,
|
||||
edition_date DATETIME,
|
||||
creator_id INTEGER NOT NULL,
|
||||
tags VARCHAR(1014)
|
||||
CHARACTER SET utf8,
|
||||
last_editor_id INTEGER NOT NULL,
|
||||
FOREIGN KEY (creator_id) REFERENCES USER (colaborator_id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION
|
||||
)
|
||||
CHARACTER SET utf8;
|
||||
|
||||
CREATE TABLE LABEL (
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
title VARCHAR(30)
|
||||
CHARACTER SET utf8 NOT NULL,
|
||||
creator_id INTEGER NOT NULL,
|
||||
parent_label_id INTEGER,
|
||||
color VARCHAR(7) NOT NULL,
|
||||
iconName VARCHAR(50) NOT NULL,
|
||||
FOREIGN KEY (creator_id) REFERENCES USER (colaborator_id),
|
||||
FOREIGN KEY (parent_label_id) REFERENCES LABEL (id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION
|
||||
)
|
||||
CHARACTER SET utf8;
|
||||
|
||||
CREATE TABLE R_LABEL_MINDMAP (
|
||||
mindmap_id INTEGER NOT NULL,
|
||||
label_id INTEGER NOT NULL,
|
||||
PRIMARY KEY (mindmap_id, label_id),
|
||||
FOREIGN KEY (mindmap_id) REFERENCES MINDMAP (id),
|
||||
FOREIGN KEY (label_id) REFERENCES LABEL (id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION
|
||||
)
|
||||
CHARACTER SET utf8;
|
||||
|
||||
CREATE TABLE MINDMAP_HISTORY
|
||||
(id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
xml MEDIUMBLOB NOT NULL,
|
||||
mindmap_id INTEGER NOT NULL,
|
||||
creation_date DATETIME,
|
||||
editor_id INTEGER NOT NULL,
|
||||
FOREIGN KEY (mindmap_id) REFERENCES MINDMAP (id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION
|
||||
)
|
||||
CHARACTER SET utf8;
|
||||
|
||||
CREATE TABLE COLLABORATION_PROPERTIES (
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
starred BOOL NOT NULL DEFAULT 0,
|
||||
mindmap_properties VARCHAR(512)
|
||||
CHARACTER SET utf8
|
||||
)
|
||||
CHARACTER SET utf8;
|
||||
|
||||
CREATE TABLE COLLABORATION (
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
colaborator_id INTEGER NOT NULL,
|
||||
properties_id INTEGER NOT NULL,
|
||||
mindmap_id INTEGER NOT NULL,
|
||||
role_id INTEGER NOT NULL,
|
||||
FOREIGN KEY (colaborator_id) REFERENCES COLLABORATOR (id),
|
||||
FOREIGN KEY (mindmap_id) REFERENCES MINDMAP (id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION,
|
||||
FOREIGN KEY (properties_id) REFERENCES COLLABORATION_PROPERTIES (id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION
|
||||
)
|
||||
CHARACTER SET utf8;
|
||||
|
||||
CREATE TABLE TAG (
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
name VARCHAR(255)
|
||||
CHARACTER SET utf8 NOT NULL,
|
||||
user_id INTEGER NOT NULL,
|
||||
FOREIGN KEY (user_id) REFERENCES USER (colaborator_id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION
|
||||
)
|
||||
CHARACTER SET utf8;
|
||||
|
||||
CREATE TABLE ACCESS_AUDITORY (
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||
login_date DATE,
|
||||
user_id INTEGER NOT NULL,
|
||||
FOREIGN KEY (user_id) REFERENCES USER (colaborator_id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE NO ACTION
|
||||
)
|
||||
CHARACTER SET utf8;
|
||||
|
||||
COMMIT;
|
13
distribution/mysql-init/0003apopulate-schemas.sql
Normal file
13
distribution/mysql-init/0003apopulate-schemas.sql
Normal file
@ -0,0 +1,13 @@
|
||||
#
|
||||
# Command: mysql -u root -p < apopulate_schemas.sql
|
||||
#
|
||||
|
||||
INSERT INTO COLLABORATOR (id, email, creation_date) VALUES (1, 'test@wisemapping.org', CURRENT_DATE());
|
||||
INSERT INTO USER (colaborator_id, firstname, lastname, password, activation_code, activation_date, allow_send_email,authentication_type)
|
||||
VALUES (1, 'Test', 'User', 'ENC:a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1237, CURRENT_DATE(), 1,'D');
|
||||
|
||||
INSERT INTO COLLABORATOR (id, email, creation_date) VALUES (2, 'admin@wisemapping.org', CURRENT_DATE());
|
||||
INSERT INTO USER (colaborator_id, firstname, lastname, password, activation_code, activation_date, allow_send_email,authentication_type)
|
||||
VALUES (2, 'Admin', 'User', 'ENC:a94a8fe5ccb19ba61c4c0873d391e987982fbbd3', 1237, CURRENT_DATE(), 1,'D');
|
||||
|
||||
COMMIT;
|
@ -1,65 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
set -u
|
||||
|
||||
WISE_VERSION=$1
|
||||
BASE_DIR=`pwd`
|
||||
TARGET_DIR=$BASE_DIR/target
|
||||
JETTY_DIR=$TARGET_DIR/wisemapping-$WISE_VERSION
|
||||
WISE_WEBAPP_DIR=$JETTY_DIR/webapps/wisemapping
|
||||
JETTY_VERSION=8.1.16.v20140903
|
||||
JETTY_DIST_DIR=jetty-distribution-${JETTY_VERSION}
|
||||
JETTY_ZIP=${JETTY_DIST_DIR}.zip
|
||||
|
||||
# Clean ...
|
||||
mvn -o -f $BASE_DIR/../pom.xml clean
|
||||
[ ! -e target ] && mkdir target
|
||||
rm -fr ${JETTY_DIR}
|
||||
rm -fr ${TARGET_DIR}/${JETTY_DIST_DIR}
|
||||
|
||||
# Prepare resources ..
|
||||
mvn -o -f $BASE_DIR/../pom.xml package -Dmaven.test.skip=true
|
||||
|
||||
if [ ! -f ./target/${JETTY_ZIP} ]
|
||||
then
|
||||
echo "Download Jetty"
|
||||
wget http://download.eclipse.org/jetty/${JETTY_VERSION}/dist/${JETTY_ZIP} -P $TARGET_DIR
|
||||
fi
|
||||
|
||||
echo "Unzip Jetty ...:"
|
||||
unzip ${TARGET_DIR}/${JETTY_ZIP} -d ${TARGET_DIR}/ > /dev/null
|
||||
mv ${TARGET_DIR}/${JETTY_DIST_DIR} ${JETTY_DIR}
|
||||
|
||||
# Clean unsed files ...
|
||||
rm -rf $JETTY_DIR/webapps/*
|
||||
rm -rf $JETTY_DIR/contexts/*
|
||||
rm -rf $JETTY_DIR/javadoc
|
||||
|
||||
# Now, start wise-webapps customization ...
|
||||
echo "Unzip wisemappig.war ..."
|
||||
mkdir $WISE_WEBAPP_DIR
|
||||
unzip $BASE_DIR/../wise-webapp/target/wisemapping.war -d $WISE_WEBAPP_DIR >/dev/null
|
||||
|
||||
# DB Configuration ...
|
||||
sed 's/\${database.base.url}\/db\/wisemapping/webapps\/wisemapping\/WEB-INF\/database\/wisemapping/' $WISE_WEBAPP_DIR/WEB-INF/app.properties > $WISE_WEBAPP_DIR/WEB-INF/app.properties2
|
||||
mv $WISE_WEBAPP_DIR/WEB-INF/app.properties2 $WISE_WEBAPP_DIR/WEB-INF/app.properties
|
||||
|
||||
mkdir $WISE_WEBAPP_DIR/WEB-INF/database
|
||||
cp -r $BASE_DIR/../wise-webapp/target/db/* $WISE_WEBAPP_DIR/WEB-INF/database/
|
||||
cp $BASE_DIR/wisemapping.xml $JETTY_DIR/contexts/
|
||||
|
||||
|
||||
# Distribute scripts
|
||||
cp -r $BASE_DIR/../config/ $TARGET_DIR/wisemapping-$WISE_VERSION/config
|
||||
cp ./start.sh ${JETTY_DIR}/
|
||||
cp -r $BASE_DIR/service $TARGET_DIR/wisemapping-$WISE_VERSION/service
|
||||
|
||||
# Store version
|
||||
echo $1 > $WISE_WEBAPP_DIR/version
|
||||
git rev-parse HEAD >> $WISE_WEBAPP_DIR/version
|
||||
|
||||
# Zip all ...
|
||||
cd $TARGET_DIR
|
||||
zip -r wisemapping-$WISE_VERSION.zip wisemapping-$WISE_VERSION
|
||||
cd ..
|
@ -1,72 +0,0 @@
|
||||
#!/bin/bash
|
||||
### BEGIN INIT INFO
|
||||
# Provides: wisemapping
|
||||
# Required-Start: $all
|
||||
# Required-Stop:
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: wisemapping
|
||||
# Description: www.wisemapping.com
|
||||
### END INIT INFO
|
||||
|
||||
set -e
|
||||
set -u
|
||||
|
||||
#environmental variables
|
||||
JAVA_HOME="/usr/lib/jvm/java7"
|
||||
JDK_HOME=$JAVA_HOME
|
||||
export PATH=$JAVA_HOME/bin:$PATH
|
||||
WISE_HOME="/opt/wisemapping"
|
||||
PID_FILE="$WISE_HOME/.pid"
|
||||
SELF=$(cd $(dirname $0); pwd -P)/$(basename $0)
|
||||
|
||||
preInitChecks() {
|
||||
MYSQL_STATUS=`pgrep mysql`
|
||||
if [ -z $MYSQL_STATUS ]; then
|
||||
service mysql start >/dev/null 2>&1
|
||||
fi
|
||||
}
|
||||
|
||||
wiseStatus() {
|
||||
echo `pgrep -f "$WISE_HOME/start.jar"`
|
||||
}
|
||||
|
||||
case "${1:-''}" in
|
||||
'start')
|
||||
#preInitChecks
|
||||
cd $WISE_HOME
|
||||
echo "Starting Wisemapping..."
|
||||
java -Xmx256m -Dorg.apache.jasper.compiler.disablejsr199=true -jar $WISE_HOME/start.jar > $WISE_HOME/logs/start.log 2>&1 &
|
||||
PID=$!
|
||||
cd - >/dev/null 2>&1
|
||||
echo "proccess id: $PID"
|
||||
echo "$PID" > $PID_FILE
|
||||
;;
|
||||
'stop')
|
||||
if [ ! -f $PID_FILE ]; then
|
||||
PID=$(wiseStatus)
|
||||
else
|
||||
PID=`cat $PID_FILE`
|
||||
rm $PID_FILE >/dev/null 2>&1
|
||||
fi
|
||||
kill $PID
|
||||
echo "Wisemapping stopped"
|
||||
;;
|
||||
'restart')
|
||||
set +e; $SELF stop; set -e
|
||||
$SELF start
|
||||
;;
|
||||
'status')
|
||||
STATUS=$(wiseStatus)
|
||||
if [ -n "$STATUS" ]; then
|
||||
echo "Wisemapping server is running, pid: $STATUS"
|
||||
else
|
||||
echo "Wisemapping is stopped"
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Usage: $SELF start|stop|restart|status"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
@ -1,4 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
java -Xmx256m -Dorg.apache.jasper.compiler.disablejsr199=true -jar start.jar
|
||||
|
@ -1,80 +0,0 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
|
||||
|
||||
<!-- ==================================================================
|
||||
Configure and deploy the wisemapping web application in $(jetty.home)/webapps/wisemapping
|
||||
|
||||
Note. If this file did not exist or used a context path other that /wisemapping
|
||||
then the default configuration of jetty.xml would discover the wisemapping
|
||||
webapplication with a WebAppDeployer. By specifying a context in this
|
||||
directory, additional configuration may be specified and hot deployments
|
||||
detected.
|
||||
===================================================================== -->
|
||||
|
||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||
|
||||
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- Required minimal context configuration : -->
|
||||
<!-- + contextPath -->
|
||||
<!-- + war OR resourceBase -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<Set name="contextPath">/wisemapping</Set>
|
||||
<Set name="resourceBase"><SystemProperty name="jetty.home" default="."/>/webapps/wisemapping
|
||||
</Set>
|
||||
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- Optional context configuration -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- <Set name="extractWAR">true</Set>
|
||||
<Set name="copyWebDir">false</Set>
|
||||
<Set name="defaultsDescriptor"><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set>
|
||||
<Set name="overrideDescriptor"><SystemProperty name="jetty.home" default="."/>/contexts/wisemapping.d/override-web.xml</Set> -->
|
||||
|
||||
<!-- virtual hosts
|
||||
<Set name="virtualHosts">
|
||||
<Array type="String">
|
||||
<Item>www.myVirtualDomain.com</Item>
|
||||
<Item>localhost</Item>
|
||||
<Item>127.0.0.1</Item>
|
||||
</Array>
|
||||
</Set>
|
||||
-->
|
||||
|
||||
<!-- disable cookies
|
||||
<Get name="sessionHandler">
|
||||
<Get name="sessionManager">
|
||||
<Set name="usingCookies" type="boolean">false</Set>
|
||||
</Get>
|
||||
</Get>
|
||||
-->
|
||||
|
||||
<Get name="securityHandler">
|
||||
<Set name="loginService">
|
||||
<New class="org.eclipse.jetty.security.HashLoginService">
|
||||
<Set name="name">Test Realm</Set>
|
||||
<Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties
|
||||
</Set>
|
||||
<!-- To enable reload of realm when properties change, uncomment the following lines -->
|
||||
<!-- changing refreshInterval (in seconds) as desired -->
|
||||
<!--
|
||||
<Set name="refreshInterval">5</Set>
|
||||
<Call name="start"></Call>
|
||||
-->
|
||||
</New>
|
||||
</Set>
|
||||
<Set name="checkWelcomeFiles">true</Set>
|
||||
</Get>
|
||||
|
||||
<!-- Non standard error page mapping -->
|
||||
<!--
|
||||
<Get name="errorHandler">
|
||||
<Call name="addErrorPage">
|
||||
<Arg type="int">500</Arg>
|
||||
<Arg type="int">599</Arg>
|
||||
<Arg type="String">/dump/errorCodeRangeMapping</Arg>
|
||||
</Call>
|
||||
</Get>
|
||||
-->
|
||||
|
||||
</Configure>
|
427
mindplot/pom.xml
427
mindplot/pom.xml
@ -1,427 +0,0 @@
|
||||
<project>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>mindplot</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Mindmap Draw JavaScript Library</name>
|
||||
|
||||
<parent>
|
||||
<groupId>org.wisemapping</groupId>
|
||||
<artifactId>wisemapping</artifactId>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
<version>5.0.1</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.wisemapping</groupId>
|
||||
<artifactId>web2d</artifactId>
|
||||
<version>${com.wisemapping.version}</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<!-- <dependency>
|
||||
<groupId>com.google.jstestdriver</groupId>
|
||||
<artifactId>maven-jstestdriver-plugin</artifactId>
|
||||
<version>1.2.2-SNAPSHOT</version>
|
||||
<scope>test</scope>
|
||||
</dependency> -->
|
||||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jstd-maven-plugin google code repo</id>
|
||||
<url>http://jstd-maven-plugin.googlecode.com/svn/maven2</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.gmaven</groupId>
|
||||
<artifactId>gmaven-plugin</artifactId>
|
||||
<version>1.4</version>
|
||||
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>generate-resources</phase>
|
||||
<goals>
|
||||
<goal>execute</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<source>
|
||||
def outdir = new File(project.basedir, 'src/main/javascript');
|
||||
if (project.packaging != 'pom') {
|
||||
def dir = new File(project.basedir, 'src/main/resources/');
|
||||
|
||||
dir.eachFile { file ->
|
||||
def matcher = file.name =~ /messages_(.+)\.properties/;
|
||||
def lang = matcher[0][1];
|
||||
def outfile = new File(outdir, "MessageBundle_${lang}.js");
|
||||
println "Converting ${file.name} to ${outfile.name}";
|
||||
|
||||
outfile.withWriter('UTF-8') { out ->
|
||||
out.writeLine "mindplot.Messages.BUNDLES['${lang.toLowerCase()}'] = { ";
|
||||
file.eachLine('UTF-8') { line ->
|
||||
if (line.trim() != "" && line[0] != '#') {
|
||||
matcher = line =~ /(.+)=(.+)/;
|
||||
out.writeLine("'${matcher[0][1]}' : \"${matcher[0][2]}\",");
|
||||
}
|
||||
}
|
||||
out.writeLine("'DUMMY' : '' ");
|
||||
out.writeLine "};"
|
||||
}
|
||||
}
|
||||
}
|
||||
</source>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>merge-js-resources</id>
|
||||
<phase>generate-resources</phase>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<tasks>
|
||||
<copy toDir="${basedir}/target/classes/">
|
||||
<fileset dir="${basedir}/src/main/javascript/">
|
||||
<include name="libraries/**/*"/>
|
||||
<include name="widget/colorPalette.*"/>
|
||||
<include name="widget/*.css"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
</tasks>
|
||||
</configuration>
|
||||
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>net.alchim31.maven</groupId>
|
||||
<artifactId>yuicompressor-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>generate-resources</phase>
|
||||
<goals>
|
||||
<goal>compress</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sourceDirectory>${basedir}/src/main/javascript</sourceDirectory>
|
||||
<outputDirectory>${basedir}/target/compress/</outputDirectory>
|
||||
<nosuffix>true</nosuffix>
|
||||
<excludes>
|
||||
<exclude>libraries/**/*.js</exclude>
|
||||
</excludes>
|
||||
<aggregations>
|
||||
<aggregation>
|
||||
<output>${project.build.directory}/classes/mindplot-min.js</output>
|
||||
<inputDir>${basedir}/target/compress</inputDir>
|
||||
<includes>
|
||||
<include>header.js</include>
|
||||
<include>Events.js</include>
|
||||
<include>Options.js</include>
|
||||
<include>${basedir}/../web2d/target/classes/web2d.svg-min.js</include>
|
||||
<include>Messages.js</include>
|
||||
<include>TopicEventDispatcher.js</include>
|
||||
<include>model/IMindmap.js</include>
|
||||
<include>model/Mindmap.js</include>
|
||||
<include>model/INodeModel.js</include>
|
||||
<include>model/NodeModel.js</include>
|
||||
<include>model/RelationshipModel.js</include>
|
||||
<include>ActionDispatcher.js</include>
|
||||
<include>StandaloneActionDispatcher.js</include>
|
||||
<include>DesignerModel.js</include>
|
||||
<include>Designer.js</include>
|
||||
<include>ScreenManager.js</include>
|
||||
<include>Workspace.js</include>
|
||||
<include>ShrinkConnector.js</include>
|
||||
<include>Keyboard.js</include>
|
||||
<include>DesignerKeyboard.js</include>
|
||||
<include>Keyboard.js</include>
|
||||
<include>TopicStyle.js</include>
|
||||
<include>NodeGraph.js</include>
|
||||
<include>Topic.js</include>
|
||||
<include>CentralTopic.js</include>
|
||||
<include>MainTopic.js</include>
|
||||
<include>DragTopic.js</include>
|
||||
<include>DragManager.js</include>
|
||||
<include>DragPivot.js</include>
|
||||
<include>ConnectionLine.js</include>
|
||||
<include>Relationship.js</include>
|
||||
<include>DragConnector.js</include>
|
||||
<include>TextEditor.js</include>
|
||||
<include>MultilineTextEditor.js</include>
|
||||
<include>TextEditorFactory.js</include>
|
||||
<include>util/Shape.js</include>
|
||||
<include>util/FadeEffect.js</include>
|
||||
<include>persistence/ModelCodeName.js</include>
|
||||
<include>persistence/XMLSerializer_Pela.js</include>
|
||||
<include>persistence/XMLSerializer_Tango.js</include>
|
||||
<include>persistence/Pela2TangoMigrator.js</include>
|
||||
<include>persistence/XMLSerializer_Beta.js</include>
|
||||
<include>persistence/Beta2PelaMigrator.js</include>
|
||||
<include>persistence/XMLSerializerFactory.js</include>
|
||||
<include>PersistenceManager.js</include>
|
||||
<include>RestPersistenceManager.js</include>
|
||||
<include>LocalStorageManager.js</include>
|
||||
<include>EditorProperties.js</include>
|
||||
<include>IconGroup.js</include>
|
||||
<include>Icon.js</include>
|
||||
<include>LinkIcon.js</include>
|
||||
<include>NoteIcon.js</include>
|
||||
<include>ActionIcon.js</include>
|
||||
<include>ImageIcon.js</include>
|
||||
<include>model/FeatureModel.js</include>
|
||||
<include>model/IconModel.js</include>
|
||||
<include>model/LinkModel.js</include>
|
||||
<include>model/NoteModel.js</include>
|
||||
<include>Command.js</include>
|
||||
<include>DesignerActionRunner.js</include>
|
||||
<include>DesignerUndoManager.js</include>
|
||||
<include>ControlPoint.js</include>
|
||||
<include>EditorOptions.js</include>
|
||||
<include>RelationshipPivot.js</include>
|
||||
<include>TopicFeature.js</include>
|
||||
<include>commands/GenericFunctionCommand.js</include>
|
||||
<include>commands/DeleteCommand.js</include>
|
||||
<include>commands/DragTopicCommand.js</include>
|
||||
<include>commands/AddTopicCommand.js</include>
|
||||
<include>commands/ChangeFeatureToTopicCommand.js</include>
|
||||
<include>commands/RemoveFeatureFromTopicCommand.js</include>
|
||||
<include>commands/AddFeatureToTopicCommand.js</include>
|
||||
<include>commands/AddRelationshipCommand.js</include>
|
||||
<include>commands/MoveControlPointCommand.js</include>
|
||||
<include>widget/ModalDialogNotifier.js</include>
|
||||
<include>widget/ToolbarNotifier.js</include>
|
||||
<include>widget/ToolbarItem.js</include>
|
||||
<include>widget/ToolbarPaneItem.js</include>
|
||||
<include>widget/NoteEditor.js</include>
|
||||
<include>widget/LinkEditor.js</include>
|
||||
<include>widget/FloatingTip.js</include>
|
||||
<include>widget/LinkIconTooltip.js</include>
|
||||
<include>widget/KeyboardShortcutTooltip.js</include>
|
||||
<include>widget/ColorPalettePanel.js</include>
|
||||
<include>widget/ListToolbarPanel.js</include>
|
||||
<include>widget/FontFamilyPanel.js</include>
|
||||
<include>widget/FontSizePanel.js</include>
|
||||
<include>widget/TopicShapePanel.js</include>
|
||||
<include>widget/IconPanel.js</include>
|
||||
<include>widget/IMenu.js</include>
|
||||
<include>widget/Menu.js</include>
|
||||
<include>TopicFeature.js</include>
|
||||
<include>layout/EventBusDispatcher.js</include>
|
||||
<include>layout/ChangeEvent.js</include>
|
||||
<include>layout/LayoutManager.js</include>
|
||||
<include>layout/Node.js</include>
|
||||
<include>layout/RootedTreeSet.js</include>
|
||||
<include>layout/ChildrenSorterStrategy.js</include>
|
||||
<include>layout/AbstractBasicSorter.js</include>
|
||||
<include>layout/BalancedSorter.js</include>
|
||||
<include>layout/SymmetricSorter.js</include>
|
||||
<include>layout/GridSorter.js</include>
|
||||
<include>layout/OriginalLayout.js</include>
|
||||
<include>layout/EventBus.js</include>
|
||||
<include>MessageBundle_en.js</include>
|
||||
<include>MessageBundle_es.js</include>
|
||||
<include>MessageBundle_de.js</include>
|
||||
<include>MessageBundle_fr.js</include>
|
||||
<include>MessageBundle_pt_BR.js</include>
|
||||
<include>MessageBundle_zh_CN.js</include>
|
||||
<include>MessageBundle_zh_TW.js</include>
|
||||
<include>MessageBundle_ca.js</include>
|
||||
<include>footer.js</include>
|
||||
</includes>
|
||||
</aggregation>
|
||||
</aggregations>
|
||||
<jswarn>false</jswarn>
|
||||
<force>false</force>
|
||||
<encoding>UTF-8</encoding>
|
||||
<statistics>false</statistics>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<skipTests>true</skipTests>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.github.searls</groupId>
|
||||
<artifactId>jasmine-maven-plugin</artifactId>
|
||||
<version>1.3.1.5</version>
|
||||
<!--<executions>-->
|
||||
<!--<execution>-->
|
||||
<!--<goals>-->
|
||||
<!--<goal>test</goal>-->
|
||||
<!--</goals>-->
|
||||
<!--</execution>-->
|
||||
<!--</executions>-->
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>net.sourceforge.htmlunit</groupId>
|
||||
<artifactId>htmlunit</artifactId>
|
||||
<version>2.15</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<configuration>
|
||||
<webDriverClassName>org.openqa.selenium.phantomjs.PhantomJSDriver</webDriverClassName>
|
||||
<webDriverCapabilities>
|
||||
<capability>
|
||||
<name>phantomjs.binary.path</name>
|
||||
<value>${phantomjs.binary}</value>
|
||||
</capability>
|
||||
</webDriverCapabilities>
|
||||
<preloadSources>
|
||||
<source>libraries/mootools/mootools-core-1.4.5-full-nocompat-yc.js</source>
|
||||
<source>lib/jquery.js</source>
|
||||
<source>lib/core.js/</source>
|
||||
<source>lib/web2d.svg-min.js</source>
|
||||
<source>libraries/hotkeys/jquery.hotkeys.js</source>
|
||||
<source>libraries/underscorejs/underscore-min.js</source>
|
||||
<source>libraries/bootstrap/js/bootstrap.js</source>
|
||||
</preloadSources>
|
||||
<sourceIncludes>
|
||||
<include>header.js</include>
|
||||
<include>Events.js</include>
|
||||
<include>Messages.js</include>
|
||||
<include>TopicEventDispatcher.js</include>
|
||||
<include>model/IMindmap.js</include>
|
||||
<include>model/Mindmap.js</include>
|
||||
<include>model/INodeModel.js</include>
|
||||
<include>model/NodeModel.js</include>
|
||||
<include>model/RelationshipModel.js</include>
|
||||
<include>ActionDispatcher.js</include>
|
||||
<include>StandaloneActionDispatcher.js</include>
|
||||
<include>DesignerModel.js</include>
|
||||
<include>Designer.js</include>
|
||||
<include>ScreenManager.js</include>
|
||||
<include>Workspace.js</include>
|
||||
<include>ShrinkConnector.js</include>
|
||||
<include>Keyboard.js</include>
|
||||
<include>DesignerKeyboard.js</include>
|
||||
<include>Keyboard.js</include>
|
||||
<include>TopicStyle.js</include>
|
||||
<include>NodeGraph.js</include>
|
||||
<include>Topic.js</include>
|
||||
<include>CentralTopic.js</include>
|
||||
<include>MainTopic.js</include>
|
||||
<include>DragTopic.js</include>
|
||||
<include>DragManager.js</include>
|
||||
<include>DragPivot.js</include>
|
||||
<include>ConnectionLine.js</include>
|
||||
<include>Relationship.js</include>
|
||||
<include>DragConnector.js</include>
|
||||
<include>TextEditor.js</include>
|
||||
<include>MultilineTextEditor.js</include>
|
||||
<include>TextEditorFactory.js</include>
|
||||
<include>util/Shape.js</include>
|
||||
<include>util/FadeEffect.js</include>
|
||||
<include>persistence/ModelCodeName.js</include>
|
||||
<include>persistence/XMLSerializer_Pela.js</include>
|
||||
<include>persistence/XMLSerializer_Tango.js</include>
|
||||
<include>persistence/Pela2TangoMigrator.js</include>
|
||||
<include>persistence/XMLSerializer_Beta.js</include>
|
||||
<include>persistence/Beta2PelaMigrator.js</include>
|
||||
<include>persistence/XMLSerializerFactory.js</include>
|
||||
<include>PersistenceManager.js</include>
|
||||
<include>RestPersistenceManager.js</include>
|
||||
<include>LocalStorageManager.js</include>
|
||||
<include>EditorProperties.js</include>
|
||||
<include>IconGroup.js</include>
|
||||
<include>Icon.js</include>
|
||||
<include>LinkIcon.js</include>
|
||||
<include>NoteIcon.js</include>
|
||||
<include>ActionIcon.js</include>
|
||||
<include>ImageIcon.js</include>
|
||||
<include>model/FeatureModel.js</include>
|
||||
<include>model/IconModel.js</include>
|
||||
<include>model/LinkModel.js</include>
|
||||
<include>model/NoteModel.js</include>
|
||||
<include>Command.js</include>
|
||||
<include>DesignerActionRunner.js</include>
|
||||
<include>DesignerUndoManager.js</include>
|
||||
<include>ControlPoint.js</include>
|
||||
<include>EditorOptions.js</include>
|
||||
<include>RelationshipPivot.js</include>
|
||||
<include>TopicFeature.js</include>
|
||||
<include>commands/GenericFunctionCommand.js</include>
|
||||
<include>commands/DeleteCommand.js</include>
|
||||
<include>commands/DragTopicCommand.js</include>
|
||||
<include>commands/AddTopicCommand.js</include>
|
||||
<include>commands/ChangeFeatureToTopicCommand.js</include>
|
||||
<include>commands/RemoveFeatureFromTopicCommand.js</include>
|
||||
<include>commands/AddFeatureToTopicCommand.js</include>
|
||||
<include>commands/AddRelationshipCommand.js</include>
|
||||
<include>commands/MoveControlPointCommand.js</include>
|
||||
<include>widget/ModalDialogNotifier.js</include>
|
||||
<include>widget/ToolbarNotifier.js</include>
|
||||
<include>widget/ToolbarItem.js</include>
|
||||
<include>widget/ToolbarPaneItem.js</include>
|
||||
<include>widget/NoteEditor.js</include>
|
||||
<include>widget/LinkEditor.js</include>
|
||||
<include>widget/FloatingTip.js</include>
|
||||
<include>widget/LinkIconTooltip.js</include>
|
||||
<include>widget/KeyboardShortcutTooltip.js</include>
|
||||
<include>widget/ColorPalettePanel.js</include>
|
||||
<include>widget/ListToolbarPanel.js</include>
|
||||
<include>widget/FontFamilyPanel.js</include>
|
||||
<include>widget/FontSizePanel.js</include>
|
||||
<include>widget/TopicShapePanel.js</include>
|
||||
<include>widget/IconPanel.js</include>
|
||||
<include>widget/IMenu.js</include>
|
||||
<include>widget/Menu.js</include>
|
||||
<include>TopicFeature.js</include>
|
||||
<include>layout/EventBusDispatcher.js</include>
|
||||
<include>layout/ChangeEvent.js</include>
|
||||
<include>layout/LayoutManager.js</include>
|
||||
<include>layout/Node.js</include>
|
||||
<include>layout/RootedTreeSet.js</include>
|
||||
<include>layout/ChildrenSorterStrategy.js</include>
|
||||
<include>layout/AbstractBasicSorter.js</include>
|
||||
<include>layout/BalancedSorter.js</include>
|
||||
<include>layout/SymmetricSorter.js</include>
|
||||
<include>layout/GridSorter.js</include>
|
||||
<include>layout/OriginalLayout.js</include>
|
||||
<include>layout/EventBus.js</include>
|
||||
<include>MessageBundle_en.js</include>
|
||||
<include>MessageBundle_es.js</include>
|
||||
<include>MessageBundle_de.js</include>
|
||||
<include>MessageBundle_fr.js</include>
|
||||
<include>MessageBundle_pt_BR.js</include>
|
||||
<include>MessageBundle_zh_CN.js</include>
|
||||
<include>MessageBundle_zh_TW.js</include>
|
||||
<include>MessageBundle_ca.js</include>
|
||||
<include>footer.js</include>
|
||||
</sourceIncludes>
|
||||
<specExcludes>
|
||||
<exclude>static/test/*.js</exclude>
|
||||
<exclude>simpleTest.js</exclude>
|
||||
</specExcludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.github.klieber</groupId>
|
||||
<artifactId>phantomjs-maven-plugin</artifactId>
|
||||
<version>0.5</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>install</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<version>1.9.2</version>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
1
mindplot/src/main/javascript/.gitignore
vendored
1
mindplot/src/main/javascript/.gitignore
vendored
@ -1 +0,0 @@
|
||||
MessageBundle_*
|
@ -1,110 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
//noinspection JSUnusedLocalSymbols
|
||||
mindplot.ActionDispatcher = new Class({
|
||||
Implements:[mindplot.Events],
|
||||
initialize: function(commandContext) {
|
||||
$assert(commandContext, "commandContext can not be null");
|
||||
},
|
||||
|
||||
addRelationship: function(model, mindmap) {
|
||||
throw "method must be implemented.";
|
||||
},
|
||||
|
||||
addTopics: function(models, parentTopicId) {
|
||||
throw "method must be implemented.";
|
||||
},
|
||||
|
||||
deleteEntities: function(topicsIds, relIds) {
|
||||
throw "method must be implemented.";
|
||||
},
|
||||
|
||||
dragTopic: function(topicId, position, order, parentTopic) {
|
||||
throw "method must be implemented.";
|
||||
},
|
||||
|
||||
moveTopic: function(topicId, position) {
|
||||
throw "method must be implemented.";
|
||||
},
|
||||
|
||||
moveControlPoint: function(ctrlPoint, point) {
|
||||
throw "method must be implemented.";
|
||||
},
|
||||
|
||||
changeFontFamilyToTopic: function(topicIds, fontFamily) {
|
||||
throw "method must be implemented.";
|
||||
},
|
||||
|
||||
changeFontStyleToTopic: function(topicsIds) {
|
||||
throw "method must be implemented.";
|
||||
},
|
||||
|
||||
changeFontColorToTopic: function(topicsIds, color) {
|
||||
throw "method must be implemented.";
|
||||
},
|
||||
|
||||
changeFontSizeToTopic : function(topicsIds, size) {
|
||||
throw "method must be implemented.";
|
||||
},
|
||||
|
||||
changeBackgroundColorToTopic: function(topicsIds, color) {
|
||||
throw "method must be implemented.";
|
||||
},
|
||||
|
||||
changeBorderColorToTopic: function(topicsIds, color) {
|
||||
throw "method must be implemented.";
|
||||
},
|
||||
|
||||
changeShapeTypeToTopic : function(topicsIds, shapeType) {
|
||||
throw "method must be implemented.";
|
||||
},
|
||||
|
||||
changeFontWeightToTopic : function(topicsIds) {
|
||||
throw "method must be implemented.";
|
||||
},
|
||||
|
||||
changeTextToTopic : function(topicsIds, text) {
|
||||
throw "method must be implemented.";
|
||||
},
|
||||
|
||||
shrinkBranch : function(topicsIds, collapse) {
|
||||
throw "method must be implemented.";
|
||||
},
|
||||
|
||||
addFeatureToTopic : function(topicId, type, attributes) {
|
||||
throw "method must be implemented.";
|
||||
},
|
||||
|
||||
changeFeatureToTopic : function(topicId, featureId, attributes) {
|
||||
throw "method must be implemented.";
|
||||
},
|
||||
|
||||
removeFeatureFromTopic : function(topicId, featureId) {
|
||||
throw "method must be implemented.";
|
||||
}
|
||||
});
|
||||
|
||||
mindplot.ActionDispatcher.setInstance = function(dispatcher) {
|
||||
mindplot.ActionDispatcher._instance = dispatcher;
|
||||
};
|
||||
|
||||
mindplot.ActionDispatcher.getInstance = function() {
|
||||
return mindplot.ActionDispatcher._instance;
|
||||
};
|
||||
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.ActionIcon = new Class({
|
||||
Extends:mindplot.Icon,
|
||||
initialize: function(topic, url) {
|
||||
this.parent(url);
|
||||
this._node = topic;
|
||||
},
|
||||
getNode:function() {
|
||||
return this._node;
|
||||
},
|
||||
|
||||
setPosition:function(x, y) {
|
||||
var size = this.getSize();
|
||||
this.getImage().setPosition(x - size.width / 2, y - size.height / 2);
|
||||
},
|
||||
|
||||
addEvent:function(event, fn) {
|
||||
this.getImage().addEvent(event, fn);
|
||||
},
|
||||
|
||||
addToGroup:function(group) {
|
||||
group.append(this.getImage());
|
||||
},
|
||||
|
||||
setVisibility:function(visible) {
|
||||
this.getImage().setVisibility(visible);
|
||||
},
|
||||
|
||||
isVisible:function() {
|
||||
return this.getImage().isVisible();
|
||||
},
|
||||
|
||||
setCursor:function(cursor) {
|
||||
return this.getImage().setCursor(cursor);
|
||||
},
|
||||
|
||||
moveToBack:function(cursor) {
|
||||
return this.getImage().moveToBack(cursor);
|
||||
},
|
||||
|
||||
moveToFront:function(cursor) {
|
||||
return this.getImage().moveToFront(cursor);
|
||||
}
|
||||
});
|
||||
|
@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.CentralTopic = new Class(/** @lends CentralTopic*/{
|
||||
|
||||
Extends:mindplot.Topic,
|
||||
/**
|
||||
* @extends mindplot.Topic
|
||||
* @constructs
|
||||
* @param model
|
||||
* @param options
|
||||
*/
|
||||
initialize:function (model, options) {
|
||||
this.parent(model, options);
|
||||
},
|
||||
|
||||
_registerEvents:function () {
|
||||
this.parent();
|
||||
|
||||
// This disable the drag of the central topic. But solves the problem of deselecting the nodes when the screen is clicked.
|
||||
this.addEvent('mousedown', function (event) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
},
|
||||
|
||||
/** */
|
||||
workoutIncomingConnectionPoint:function () {
|
||||
return this.getPosition();
|
||||
},
|
||||
|
||||
/** */
|
||||
setCursor:function (type) {
|
||||
type = (type == 'move') ? 'default' : type;
|
||||
this.parent(type);
|
||||
},
|
||||
|
||||
/** */
|
||||
updateTopicShape:function () {
|
||||
|
||||
},
|
||||
|
||||
_updatePositionOnChangeSize:function () {
|
||||
|
||||
// Center main topic ...
|
||||
var zeroPoint = new core.Point(0, 0);
|
||||
this.setPosition(zeroPoint);
|
||||
},
|
||||
|
||||
/** */
|
||||
getShrinkConnector:function () {
|
||||
return null;
|
||||
},
|
||||
|
||||
/** */
|
||||
workoutOutgoingConnectionPoint:function (targetPosition) {
|
||||
$assert(targetPosition, 'targetPoint can not be null');
|
||||
var pos = this.getPosition();
|
||||
var isAtRight = mindplot.util.Shape.isAtRight(targetPosition, pos);
|
||||
var size = this.getSize();
|
||||
return mindplot.util.Shape.calculateRectConnectionPoint(pos, size, !isAtRight);
|
||||
}
|
||||
});
|
@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.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;
|
||||
}
|
||||
});
|
||||
|
||||
mindplot.Command._nextUUID = function()
|
||||
{
|
||||
if (!$defined(mindplot.Command._uuid))
|
||||
{
|
||||
mindplot.Command._uuid = 1;
|
||||
}
|
||||
|
||||
mindplot.Command._uuid = mindplot.Command._uuid + 1;
|
||||
return mindplot.Command._uuid;
|
||||
};
|
@ -1,204 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.ConnectionLine = new Class({
|
||||
initialize:function (sourceNode, targetNode, lineType) {
|
||||
$assert(targetNode, 'parentNode node can not be null');
|
||||
$assert(sourceNode, 'childNode node can not be null');
|
||||
$assert(sourceNode != targetNode, 'Circular connection');
|
||||
|
||||
this._targetTopic = targetNode;
|
||||
this._sourceTopic = sourceNode;
|
||||
|
||||
var line;
|
||||
var ctrlPoints = this._getCtrlPoints(sourceNode, targetNode);
|
||||
if (targetNode.getType() == mindplot.model.INodeModel.CENTRAL_TOPIC_TYPE) {
|
||||
line = this._createLine(lineType, mindplot.ConnectionLine.CURVED);
|
||||
line.setSrcControlPoint(ctrlPoints[0]);
|
||||
line.setDestControlPoint(ctrlPoints[1]);
|
||||
} else {
|
||||
line = this._createLine(lineType, mindplot.ConnectionLine.SIMPLE_CURVED);
|
||||
line.setSrcControlPoint(ctrlPoints[0]);
|
||||
line.setDestControlPoint(ctrlPoints[1]);
|
||||
}
|
||||
// Set line styles ...
|
||||
var strokeColor = mindplot.ConnectionLine.getStrokeColor();
|
||||
line.setStroke(1, 'solid', strokeColor, 1);
|
||||
line.setFill(strokeColor, 1);
|
||||
|
||||
this._line2d = line;
|
||||
},
|
||||
|
||||
_getCtrlPoints:function (sourceNode, targetNode) {
|
||||
var srcPos = sourceNode.workoutOutgoingConnectionPoint(targetNode.getPosition());
|
||||
var destPos = targetNode.workoutIncomingConnectionPoint(sourceNode.getPosition());
|
||||
var deltaX = (srcPos.x - destPos.x) / 3;
|
||||
return [new core.Point(deltaX, 0), new core.Point(-deltaX, 0)];
|
||||
},
|
||||
|
||||
_createLine:function (lineType, defaultStyle) {
|
||||
if (!$defined(lineType)) {
|
||||
lineType = defaultStyle;
|
||||
}
|
||||
lineType = parseInt(lineType);
|
||||
this._lineType = lineType;
|
||||
var line = null;
|
||||
switch (lineType) {
|
||||
case mindplot.ConnectionLine.POLYLINE:
|
||||
line = new web2d.PolyLine();
|
||||
break;
|
||||
case mindplot.ConnectionLine.CURVED:
|
||||
line = new web2d.CurvedLine();
|
||||
break;
|
||||
case mindplot.ConnectionLine.SIMPLE_CURVED:
|
||||
line = new web2d.CurvedLine();
|
||||
line.setStyle(web2d.CurvedLine.SIMPLE_LINE);
|
||||
break;
|
||||
default:
|
||||
line = new web2d.Line();
|
||||
break;
|
||||
}
|
||||
return line;
|
||||
},
|
||||
|
||||
setVisibility:function (value) {
|
||||
this._line2d.setVisibility(value);
|
||||
},
|
||||
|
||||
isVisible:function () {
|
||||
return this._line2d.isVisible();
|
||||
},
|
||||
|
||||
setOpacity:function (opacity) {
|
||||
this._line2d.setOpacity(opacity);
|
||||
},
|
||||
|
||||
redraw:function () {
|
||||
var line2d = this._line2d;
|
||||
var sourceTopic = this._sourceTopic;
|
||||
var sourcePosition = sourceTopic.getPosition();
|
||||
|
||||
var targetTopic = this._targetTopic;
|
||||
var targetPosition = targetTopic.getPosition();
|
||||
|
||||
var sPos, tPos;
|
||||
sPos = sourceTopic.workoutOutgoingConnectionPoint(targetPosition);
|
||||
tPos = targetTopic.workoutIncomingConnectionPoint(sourcePosition);
|
||||
|
||||
line2d.setFrom(tPos.x, tPos.y);
|
||||
line2d.setTo(sPos.x, sPos.y);
|
||||
|
||||
if (line2d.getType() == "CurvedLine") {
|
||||
var ctrlPoints = this._getCtrlPoints(this._sourceTopic, this._targetTopic);
|
||||
line2d.setSrcControlPoint(ctrlPoints[0]);
|
||||
line2d.setDestControlPoint(ctrlPoints[1]);
|
||||
}
|
||||
|
||||
// Add connector ...
|
||||
this._positionateConnector(targetTopic);
|
||||
|
||||
},
|
||||
|
||||
_positionateConnector:function (targetTopic) {
|
||||
var targetPosition = targetTopic.getPosition();
|
||||
var offset = mindplot.Topic.CONNECTOR_WIDTH / 2;
|
||||
var targetTopicSize = targetTopic.getSize();
|
||||
var y, x;
|
||||
if (targetTopic.getShapeType() == mindplot.model.TopicShape.LINE) {
|
||||
y = targetTopicSize.height;
|
||||
} else {
|
||||
y = targetTopicSize.height / 2;
|
||||
}
|
||||
y = y - offset;
|
||||
|
||||
var connector = targetTopic.getShrinkConnector();
|
||||
if ($defined(connector)) {
|
||||
if (Math.sign(targetPosition.x) > 0) {
|
||||
x = targetTopicSize.width;
|
||||
connector.setPosition(x, y);
|
||||
}
|
||||
else {
|
||||
x = -mindplot.Topic.CONNECTOR_WIDTH;
|
||||
}
|
||||
connector.setPosition(x, y);
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
setStroke:function (color, style, opacity) {
|
||||
this._line2d.setStroke(null, null, color, opacity);
|
||||
},
|
||||
|
||||
addToWorkspace:function (workspace) {
|
||||
workspace.append(this._line2d);
|
||||
this._line2d.moveToBack();
|
||||
},
|
||||
|
||||
removeFromWorkspace:function (workspace) {
|
||||
workspace.removeChild(this._line2d);
|
||||
},
|
||||
|
||||
getTargetTopic:function () {
|
||||
return this._targetTopic;
|
||||
},
|
||||
|
||||
getSourceTopic:function () {
|
||||
return this._sourceTopic;
|
||||
},
|
||||
|
||||
getLineType:function () {
|
||||
return this._lineType;
|
||||
},
|
||||
|
||||
getLine:function () {
|
||||
return this._line2d;
|
||||
},
|
||||
|
||||
getModel:function () {
|
||||
return this._model;
|
||||
},
|
||||
|
||||
setModel:function (model) {
|
||||
this._model = model;
|
||||
},
|
||||
|
||||
getType:function () {
|
||||
return "ConnectionLine";
|
||||
},
|
||||
|
||||
getId:function () {
|
||||
return this._model.getId();
|
||||
},
|
||||
|
||||
moveToBack:function () {
|
||||
this._line2d.moveToBack();
|
||||
},
|
||||
|
||||
moveToFront:function () {
|
||||
this._line2d.moveToFront();
|
||||
}
|
||||
});
|
||||
|
||||
mindplot.ConnectionLine.getStrokeColor = function () {
|
||||
return '#495879';
|
||||
};
|
||||
|
||||
mindplot.ConnectionLine.SIMPLE = 0;
|
||||
mindplot.ConnectionLine.POLYLINE = 1;
|
||||
mindplot.ConnectionLine.CURVED = 2;
|
||||
mindplot.ConnectionLine.SIMPLE_CURVED = 3;
|
@ -1,202 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.ControlPoint = new Class({
|
||||
initialize: function () {
|
||||
var control1 = new web2d.Elipse({
|
||||
width: 6,
|
||||
height: 6,
|
||||
stroke: '1 solid #6589de',
|
||||
fillColor: 'gray',
|
||||
visibility: false
|
||||
});
|
||||
control1.setCursor('pointer');
|
||||
|
||||
var control2 = new web2d.Elipse({
|
||||
width: 6,
|
||||
height: 6,
|
||||
stroke: '1 solid #6589de',
|
||||
fillColor: 'gray',
|
||||
visibility: false
|
||||
});
|
||||
control2.setCursor('pointer');
|
||||
|
||||
this._controlPointsController = [control1, control2];
|
||||
this._controlLines = [new web2d.Line({strokeColor: "#6589de", strokeWidth: 1, opacity: 0.3}),
|
||||
new web2d.Line({strokeColor: "#6589de", strokeWidth: 1, opacity: 0.3})];
|
||||
|
||||
this._isBinded = false;
|
||||
var me = this;
|
||||
this._controlPointsController[0].addEvent('mousedown', function (event) {
|
||||
(me._mouseDown)(event, mindplot.ControlPoint.FROM, me);
|
||||
});
|
||||
this._controlPointsController[0].addEvent('click', function (event) {
|
||||
(me._mouseClick)(event);
|
||||
});
|
||||
this._controlPointsController[0].addEvent('dblclick', function (event) {
|
||||
(me._mouseClick)(event);
|
||||
});
|
||||
|
||||
this._controlPointsController[1].addEvent('mousedown', function (event) {
|
||||
(me._mouseDown)(event, mindplot.ControlPoint.TO, me);
|
||||
});
|
||||
this._controlPointsController[1].addEvent('click', function (event) {
|
||||
(me._mouseClick)(event);
|
||||
});
|
||||
this._controlPointsController[1].addEvent('dblclick', function (event) {
|
||||
(me._mouseClick)(event);
|
||||
});
|
||||
},
|
||||
|
||||
setLine: function (line) {
|
||||
if ($defined(this._line)) {
|
||||
this._removeLine();
|
||||
}
|
||||
this._line = line;
|
||||
this._createControlPoint();
|
||||
this._endPoint = [];
|
||||
this._orignalCtrlPoint = [];
|
||||
this._orignalCtrlPoint[0] = this._controls[0].clone();
|
||||
this._orignalCtrlPoint[1] = this._controls[1].clone();
|
||||
this._endPoint[0] = this._line.getLine().getFrom().clone();
|
||||
this._endPoint[1] = this._line.getLine().getTo().clone();
|
||||
},
|
||||
|
||||
redraw: function () {
|
||||
if ($defined(this._line))
|
||||
this._createControlPoint();
|
||||
},
|
||||
|
||||
_createControlPoint: function () {
|
||||
this._controls = this._line.getLine().getControlPoints();
|
||||
var pos = this._line.getLine().getFrom();
|
||||
this._controlPointsController[0].setPosition(this._controls[mindplot.ControlPoint.FROM].x + pos.x, this._controls[mindplot.ControlPoint.FROM].y + pos.y - 3);
|
||||
this._controlLines[0].setFrom(pos.x, pos.y);
|
||||
this._controlLines[0].setTo(this._controls[mindplot.ControlPoint.FROM].x + pos.x + 3, this._controls[mindplot.ControlPoint.FROM].y + pos.y);
|
||||
pos = this._line.getLine().getTo();
|
||||
this._controlLines[1].setFrom(pos.x, pos.y);
|
||||
this._controlLines[1].setTo(this._controls[mindplot.ControlPoint.TO].x + pos.x + 3, this._controls[mindplot.ControlPoint.TO].y + pos.y);
|
||||
this._controlPointsController[1].setPosition(this._controls[mindplot.ControlPoint.TO].x + pos.x, this._controls[mindplot.ControlPoint.TO].y + pos.y - 3);
|
||||
|
||||
},
|
||||
|
||||
_removeLine: function () {
|
||||
|
||||
},
|
||||
|
||||
_mouseDown: function (event, point, me) {
|
||||
if (!this._isBinded) {
|
||||
this._isBinded = true;
|
||||
this._mouseMoveFunction = function (event) {
|
||||
(me._mouseMoveEvent)(event, point, me);
|
||||
};
|
||||
|
||||
this._workspace.getScreenManager().addEvent('mousemove', this._mouseMoveFunction);
|
||||
this._mouseUpFunction = function (event) {
|
||||
(me._mouseUp)(event, point, me);
|
||||
};
|
||||
this._workspace.getScreenManager().addEvent('mouseup', this._mouseUpFunction);
|
||||
}
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
},
|
||||
|
||||
_mouseMoveEvent: function (event, point) {
|
||||
var screen = this._workspace.getScreenManager();
|
||||
var pos = screen.getWorkspaceMousePosition(event);
|
||||
|
||||
var cords;
|
||||
if (point == 0) {
|
||||
cords = mindplot.util.Shape.calculateRelationShipPointCoordinates(this._line.getSourceTopic(), pos);
|
||||
this._line.setFrom(cords.x, cords.y);
|
||||
this._line.setSrcControlPoint(new core.Point(pos.x - cords.x, pos.y - cords.y));
|
||||
} else {
|
||||
cords = mindplot.util.Shape.calculateRelationShipPointCoordinates(this._line.getTargetTopic(), pos);
|
||||
this._line.setTo(cords.x, cords.y);
|
||||
this._line.setDestControlPoint(new core.Point(pos.x - cords.x, pos.y - cords.y));
|
||||
}
|
||||
|
||||
this._controls[point].x = (pos.x - cords.x);
|
||||
this._controls[point].y = (pos.y - cords.y);
|
||||
this._controlPointsController[point].setPosition(pos.x - 5, pos.y - 3);
|
||||
this._controlLines[point].setFrom(cords.x, cords.y);
|
||||
this._controlLines[point].setTo(pos.x - 2, pos.y);
|
||||
this._line.getLine().updateLine(point);
|
||||
|
||||
},
|
||||
|
||||
_mouseUp: function (event, point) {
|
||||
this._workspace.getScreenManager().removeEvent('mousemove', this._mouseMoveFunction);
|
||||
this._workspace.getScreenManager().removeEvent('mouseup', this._mouseUpFunction);
|
||||
|
||||
var actionDispatcher = mindplot.ActionDispatcher.getInstance();
|
||||
actionDispatcher.moveControlPoint(this, point);
|
||||
this._isBinded = false;
|
||||
},
|
||||
|
||||
_mouseClick: function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
},
|
||||
|
||||
setVisibility: function (visible) {
|
||||
if (visible) {
|
||||
this._controlLines[0].moveToFront();
|
||||
this._controlLines[1].moveToFront();
|
||||
this._controlPointsController[0].moveToFront();
|
||||
this._controlPointsController[1].moveToFront();
|
||||
}
|
||||
this._controlPointsController[0].setVisibility(visible);
|
||||
this._controlPointsController[1].setVisibility(visible);
|
||||
this._controlLines[0].setVisibility(visible);
|
||||
this._controlLines[1].setVisibility(visible);
|
||||
},
|
||||
|
||||
addToWorkspace: function (workspace) {
|
||||
this._workspace = workspace;
|
||||
workspace.append(this._controlPointsController[0]);
|
||||
workspace.append(this._controlPointsController[1]);
|
||||
workspace.append(this._controlLines[0]);
|
||||
workspace.append(this._controlLines[1]);
|
||||
},
|
||||
|
||||
removeFromWorkspace: function (workspace) {
|
||||
this._workspace = null;
|
||||
workspace.removeChild(this._controlPointsController[0]);
|
||||
workspace.removeChild(this._controlPointsController[1]);
|
||||
workspace.removeChild(this._controlLines[0]);
|
||||
workspace.removeChild(this._controlLines[1]);
|
||||
},
|
||||
|
||||
getControlPoint: function (index) {
|
||||
return this._controls[index];
|
||||
},
|
||||
|
||||
getOriginalEndPoint: function (index) {
|
||||
return this._endPoint[index];
|
||||
},
|
||||
|
||||
getOriginalCtrlPoint: function (index) {
|
||||
return this._orignalCtrlPoint[index];
|
||||
}
|
||||
});
|
||||
|
||||
mindplot.ControlPoint.FROM = 0;
|
||||
mindplot.ControlPoint.TO = 1;
|
File diff suppressed because it is too large
Load Diff
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.DesignerActionRunner = new Class({
|
||||
initialize: function (commandContext, notifier) {
|
||||
$assert(commandContext, "commandContext can not be null");
|
||||
|
||||
this._undoManager = new mindplot.DesignerUndoManager();
|
||||
this._context = commandContext;
|
||||
this._notifier = notifier;
|
||||
},
|
||||
|
||||
execute: function (command) {
|
||||
$assert(command, "command can not be null");
|
||||
command.execute(this._context);
|
||||
this._undoManager.enqueue(command);
|
||||
this.fireChangeEvent();
|
||||
mindplot.EventBus.instance.fireEvent(mindplot.EventBus.events.DoLayout);
|
||||
|
||||
},
|
||||
|
||||
undo: function () {
|
||||
this._undoManager.execUndo(this._context);
|
||||
this.fireChangeEvent();
|
||||
mindplot.EventBus.instance.fireEvent(mindplot.EventBus.events.DoLayout);
|
||||
},
|
||||
|
||||
redo: function () {
|
||||
this._undoManager.execRedo(this._context);
|
||||
this.fireChangeEvent();
|
||||
mindplot.EventBus.instance.fireEvent(mindplot.EventBus.events.DoLayout);
|
||||
|
||||
},
|
||||
|
||||
fireChangeEvent: function () {
|
||||
var event = this._undoManager.buildEvent();
|
||||
this._notifier.fireEvent("modelUpdate", event);
|
||||
}
|
||||
});
|
@ -1,397 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.DesignerKeyboard = new Class({
|
||||
Extends: mindplot.Keyboard,
|
||||
Static:{
|
||||
register:function (designer) {
|
||||
this._instance = new mindplot.DesignerKeyboard(designer);
|
||||
},
|
||||
|
||||
getInstance:function () {
|
||||
return this._instance;
|
||||
}
|
||||
},
|
||||
|
||||
initialize:function (designer) {
|
||||
$assert(designer, "designer can not be null");
|
||||
this._registerEvents(designer);
|
||||
},
|
||||
|
||||
_registerEvents:function (designer) {
|
||||
|
||||
// Try with the keyboard ..
|
||||
var model = designer.getModel();
|
||||
this.addShortcut(
|
||||
['backspace'], function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
designer.deleteSelectedEntities();
|
||||
}
|
||||
);
|
||||
this.addShortcut(
|
||||
['space'], function() {
|
||||
designer.shrinkSelectedBranch();
|
||||
}
|
||||
);
|
||||
this.addShortcut(
|
||||
['f2'],function(event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
var node = model.selectedTopic();
|
||||
if (node) {
|
||||
node.showTextEditor();
|
||||
}
|
||||
}
|
||||
);
|
||||
this.addShortcut(
|
||||
['del'], function(event) {
|
||||
designer.deleteSelectedEntities();
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
);
|
||||
this.addShortcut(
|
||||
['enter'], function() {
|
||||
designer.createSiblingForSelectedNode();
|
||||
}
|
||||
);
|
||||
this.addShortcut(
|
||||
['insert'], function(event) {
|
||||
designer.createChildForSelectedNode();
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
);
|
||||
this.addShortcut(
|
||||
['tab'], function(event) {
|
||||
designer.createChildForSelectedNode();
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
);
|
||||
this.addShortcut(
|
||||
['meta+enter'], function(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
designer.createChildForSelectedNode();
|
||||
}
|
||||
);
|
||||
this.addShortcut(
|
||||
['ctrl+z', 'meta+z'], function(event) {
|
||||
event.preventDefault(event);
|
||||
event.stopPropagation();
|
||||
designer.undo();
|
||||
}
|
||||
);
|
||||
this.addShortcut(
|
||||
['ctrl+c', 'meta+c'], function (event) {
|
||||
event.preventDefault(event);
|
||||
event.stopPropagation();
|
||||
designer.copyToClipboard();
|
||||
}
|
||||
);
|
||||
this.addShortcut(
|
||||
['ctrl+v', 'meta+v'], function (event) {
|
||||
event.preventDefault(event);
|
||||
event.stopPropagation();
|
||||
designer.pasteClipboard();
|
||||
}
|
||||
);
|
||||
this.addShortcut(
|
||||
['ctrl+shift+z', 'meta+shift+z', 'ctrl+y', 'meta+y'], function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
designer.redo();
|
||||
}
|
||||
);
|
||||
this.addShortcut(
|
||||
['ctrl+a', 'meta+a'], function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
designer.selectAll();
|
||||
}
|
||||
);
|
||||
this.addShortcut(
|
||||
['ctrl+b', 'meta+b'], function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
designer.changeFontWeight();
|
||||
}
|
||||
);
|
||||
this.addShortcut(
|
||||
['ctrl+s', 'meta+s'], function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
$(document).find('#save').trigger('click');
|
||||
}
|
||||
);
|
||||
this.addShortcut(
|
||||
['ctrl+i', 'meta+i'], function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
designer.changeFontStyle();
|
||||
}
|
||||
);
|
||||
this.addShortcut(
|
||||
['ctrl+shift+a', 'meta+shift+a'], function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
designer.deselectAll();
|
||||
}
|
||||
);
|
||||
this.addShortcut(
|
||||
['meta+=', 'ctrl+='], function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
designer.zoomIn();
|
||||
}
|
||||
);
|
||||
this.addShortcut(
|
||||
['meta+-', 'ctrl+-'], function (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
designer.zoomOut();
|
||||
}
|
||||
);
|
||||
var me = this;
|
||||
this.addShortcut(
|
||||
'right', function (event) {
|
||||
var node = model.selectedTopic();
|
||||
if (node) {
|
||||
if (node.isCentralTopic()) {
|
||||
me._goToSideChild(designer, node, 'RIGHT');
|
||||
}
|
||||
else {
|
||||
if (node.getPosition().x < 0) {
|
||||
me._goToParent(designer, node);
|
||||
}
|
||||
else if (!node.areChildrenShrunken()) {
|
||||
me._goToChild(designer, node);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var centralTopic = model.getCentralTopic();
|
||||
me._goToNode(designer, centralTopic);
|
||||
}
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
);
|
||||
this.addShortcut(
|
||||
'left', function (event) {
|
||||
var node = model.selectedTopic();
|
||||
if (node) {
|
||||
if (node.isCentralTopic()) {
|
||||
me._goToSideChild(designer, node, 'LEFT');
|
||||
}
|
||||
else {
|
||||
if (node.getPosition().x > 0) {
|
||||
me._goToParent(designer, node);
|
||||
}
|
||||
else if (!node.areChildrenShrunken()) {
|
||||
me._goToChild(designer, node);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
var centralTopic = model.getCentralTopic();
|
||||
me._goToNode(designer, centralTopic);
|
||||
}
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
);
|
||||
this.addShortcut(
|
||||
'up', function (event) {
|
||||
var node = model.selectedTopic();
|
||||
if (node) {
|
||||
if (!node.isCentralTopic()) {
|
||||
me._goToBrother(designer, node, 'UP');
|
||||
}
|
||||
} else {
|
||||
var centralTopic = model.getCentralTopic();
|
||||
me._goToNode(designer, centralTopic);
|
||||
}
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
);
|
||||
this.addShortcut(
|
||||
'down', function (event) {
|
||||
var node = model.selectedTopic();
|
||||
if (node) {
|
||||
if (!node.isCentralTopic()) {
|
||||
me._goToBrother(designer, node, 'DOWN');
|
||||
}
|
||||
} else {
|
||||
var centralTopic = model.getCentralTopic();
|
||||
me._goToNode(designer, centralTopic);
|
||||
}
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
);
|
||||
var excludes = ['esc', 'escape', 'f1', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10', 'f11', 'f12'];
|
||||
|
||||
$(document).on('keypress', function (event) {
|
||||
var keyCode;
|
||||
// Firefox doesn't skip special keys for keypress event...
|
||||
if (event.key && excludes.contains(event.key.toLowerCase())) {
|
||||
return;
|
||||
}
|
||||
// Sometimes Firefox doesn't contain keyCode value
|
||||
if (event.key && event.keyCode == 0) {
|
||||
keyCode = event.charCode;
|
||||
} else {
|
||||
keyCode = event.keyCode;
|
||||
}
|
||||
|
||||
var specialKey = jQuery.hotkeys.specialKeys[keyCode];
|
||||
if (["enter", "capslock"].indexOf(specialKey) == -1 && !jQuery.hotkeys.shiftNums[keyCode]) {
|
||||
var nodes = designer.getModel().filterSelectedTopics();
|
||||
if (nodes.length > 0) {
|
||||
|
||||
// If a modifier is press, the key selected must be ignored.
|
||||
var pressKey = String.fromCharCode(keyCode);
|
||||
if (event.ctrlKey || event.altKey || event.metaKey) {
|
||||
return;
|
||||
}
|
||||
nodes[0].showTextEditor(pressKey);
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
_goToBrother:function (designer, node, direction) {
|
||||
var parent = node.getParent();
|
||||
if (parent) {
|
||||
var brothers = parent.getChildren();
|
||||
|
||||
var target = node;
|
||||
var y = node.getPosition().y;
|
||||
var x = node.getPosition().x;
|
||||
var dist = null;
|
||||
for (var i = 0; i < brothers.length; i++) {
|
||||
var sameSide = (x * brothers[i].getPosition().x) >= 0;
|
||||
if (brothers[i] != node && sameSide) {
|
||||
var brother = brothers[i];
|
||||
var brotherY = brother.getPosition().y;
|
||||
if (direction == "DOWN" && brotherY > y) {
|
||||
var distancia = y - brotherY;
|
||||
if (distancia < 0) {
|
||||
distancia = distancia * (-1);
|
||||
}
|
||||
if (dist == null || dist > distancia) {
|
||||
dist = distancia;
|
||||
target = brothers[i];
|
||||
}
|
||||
}
|
||||
else if (direction == "UP" && brotherY < y) {
|
||||
var distance = y - brotherY;
|
||||
if (distance < 0) {
|
||||
distance = distance * (-1);
|
||||
}
|
||||
if (dist == null || dist > distance) {
|
||||
dist = distance;
|
||||
target = brothers[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this._goToNode(designer, target);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
_goToSideChild:function (designer, node, side) {
|
||||
var children = node.getChildren();
|
||||
if (children.length > 0) {
|
||||
var target = children[0];
|
||||
var top = null;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
var childY = child.getPosition().y;
|
||||
if (side == 'LEFT' && child.getPosition().x < 0) {
|
||||
if (top == null || childY < top) {
|
||||
target = child;
|
||||
top = childY;
|
||||
}
|
||||
}
|
||||
if (side == 'RIGHT' && child.getPosition().x > 0) {
|
||||
if (top == null || childY < top) {
|
||||
target = child;
|
||||
top = childY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._goToNode(designer, target);
|
||||
}
|
||||
},
|
||||
|
||||
_goToParent:function (designer, node) {
|
||||
var parent = node.getParent();
|
||||
if (parent) {
|
||||
this._goToNode(designer, parent);
|
||||
}
|
||||
},
|
||||
|
||||
_goToChild:function (designer, node) {
|
||||
var children = node.getChildren();
|
||||
if (children.length > 0) {
|
||||
var target = children[0];
|
||||
var top = target.getPosition().y;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
if (child.getPosition().y < top) {
|
||||
top = child.getPosition().y;
|
||||
target = child;
|
||||
}
|
||||
}
|
||||
this._goToNode(designer, target);
|
||||
}
|
||||
},
|
||||
|
||||
_goToNode:function (designer, node) {
|
||||
// First deselect all the nodes ...
|
||||
designer.deselectAll();
|
||||
|
||||
// Give focus to the selected node....
|
||||
node.setOnFocus(true);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
mindplot.DesignerKeyboard.specialKeys = {
|
||||
8: "backspace", 9: "tab", 10: "return", 13: "enter", 16: "shift", 17: "ctrl", 18: "alt", 19: "pause",
|
||||
20: "capslock", 27: "esc", 32: "space", 33: "pageup", 34: "pagedown", 35: "end", 36: "home",
|
||||
37: "left", 38: "up", 39: "right", 40: "down", 45: "insert", 46: "del",
|
||||
96: "0", 97: "1", 98: "2", 99: "3", 100: "4", 101: "5", 102: "6", 103: "7",
|
||||
104: "8", 105: "9", 106: "*", 107: "+", 109: "-", 110: ".", 111 : "/",
|
||||
112: "f1", 113: "f2", 114: "f3", 115: "f4", 116: "f5", 117: "f6", 118: "f7", 119: "f8",
|
||||
120: "f9", 121: "f10", 122: "f11", 123: "f12", 144: "numlock", 145: "scroll", 186: ";", 191: "/",
|
||||
220: "\\", 222: "'", 224: "meta"
|
||||
};
|
@ -1,188 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.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++) {
|
||||
if (this._topics[i].isOnFocus()) {
|
||||
result.push(this._topics[i]);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {mindplot.Relationship[]} selected relationships
|
||||
*/
|
||||
filterSelectedRelationships:function () {
|
||||
var result = [];
|
||||
for (var i = 0; i < this._relationships.length; i++) {
|
||||
if (this._relationships[i].isOnFocus()) {
|
||||
result.push(this._relationships[i]);
|
||||
}
|
||||
}
|
||||
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();
|
||||
|
||||
|
||||
var isValid = true;
|
||||
for (var i = 0; i < topics.length; i++) {
|
||||
var selectedNode = topics[i];
|
||||
if ($defined(validate)) {
|
||||
isValid = validate(selectedNode);
|
||||
}
|
||||
|
||||
// Add node only if it's valid.
|
||||
if (isValid) {
|
||||
result.push(selectedNode.getId());
|
||||
} else {
|
||||
$notify(errorMsg);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {mindplot.Topic} the first selected topic if one or more are found by the
|
||||
* 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++) {
|
||||
var topic = this._topics[i];
|
||||
if (topic.getId() == id) {
|
||||
result = topic;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
});
|
@ -1,83 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.DesignerUndoManager = new Class({
|
||||
initialize: function(fireChange) {
|
||||
this._undoQueue = [];
|
||||
this._redoQueue = [];
|
||||
this._baseId = 0;
|
||||
},
|
||||
|
||||
enqueue:function(command) {
|
||||
$assert(command, "Command can not be null");
|
||||
var length = this._undoQueue.length;
|
||||
if (command.discardDuplicated && length > 0) {
|
||||
// Skip duplicated events ...
|
||||
var lastItem = this._undoQueue[length - 1];
|
||||
if (lastItem.discardDuplicated != command.discardDuplicated) {
|
||||
this._undoQueue.push(command);
|
||||
}
|
||||
} else {
|
||||
this._undoQueue.push(command);
|
||||
}
|
||||
this._redoQueue = [];
|
||||
},
|
||||
|
||||
execUndo: function(commandContext) {
|
||||
if (this._undoQueue.length > 0) {
|
||||
var command = this._undoQueue.pop();
|
||||
this._redoQueue.push(command);
|
||||
|
||||
command.undoExecute(commandContext);
|
||||
}
|
||||
},
|
||||
|
||||
execRedo: function(commandContext) {
|
||||
if (this._redoQueue.length > 0) {
|
||||
var command = this._redoQueue.pop();
|
||||
this._undoQueue.push(command);
|
||||
command.execute(commandContext);
|
||||
}
|
||||
},
|
||||
|
||||
buildEvent: function() {
|
||||
return {undoSteps: this._undoQueue.length, redoSteps:this._redoQueue.length};
|
||||
},
|
||||
|
||||
markAsChangeBase: function() {
|
||||
var undoLength = this._undoQueue.length;
|
||||
if (undoLength > 0) {
|
||||
var command = this._undoQueue[undoLength - 1];
|
||||
this._baseId = command.getId();
|
||||
} else {
|
||||
this._baseId = 0;
|
||||
}
|
||||
},
|
||||
|
||||
hasBeenChanged: function() {
|
||||
var result = true;
|
||||
var undoLength= this._undoQueue.length;
|
||||
if (undoLength == 0 && this._baseId == 0) {
|
||||
result = false;
|
||||
} else if (undoLength > 0) {
|
||||
var command = this._undoQueue[undoLength - 1];
|
||||
result = (this._baseId != command.getId());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
});
|
@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.DragConnector = new Class({
|
||||
initialize:function (designerModel, workspace) {
|
||||
$assert(designerModel, 'designerModel can not be null');
|
||||
$assert(workspace, 'workspace can not be null');
|
||||
|
||||
// this._layoutManager = layoutManager;
|
||||
this._designerModel = designerModel;
|
||||
this._workspace = workspace;
|
||||
},
|
||||
|
||||
checkConnection:function (dragTopic) {
|
||||
var topics = this._designerModel.getTopics();
|
||||
|
||||
// Must be disconnected from their current connection ?.
|
||||
var candidates = this._searchConnectionCandidates(dragTopic);
|
||||
var currentConnection = dragTopic.getConnectedToTopic();
|
||||
|
||||
|
||||
if (currentConnection && (candidates.length == 0 || candidates[0] != currentConnection)) {
|
||||
dragTopic.disconnect(this._workspace);
|
||||
}
|
||||
|
||||
// Finally, connect nodes ...
|
||||
if (!dragTopic.isConnected() && candidates.length > 0) {
|
||||
dragTopic.connectTo(candidates[0]);
|
||||
}
|
||||
},
|
||||
|
||||
_searchConnectionCandidates:function (dragTopic) {
|
||||
var topics = this._designerModel.getTopics();
|
||||
var draggedNode = dragTopic.getDraggedTopic();
|
||||
|
||||
// Drag node connects to the border ...
|
||||
var dragTopicWidth = dragTopic.getSize ? dragTopic.getSize().width : 0; // Hack...
|
||||
var xMouseGap = dragTopic.getPosition().x > 0 ? 0 : dragTopicWidth;
|
||||
var sPos = {x:dragTopic.getPosition().x - xMouseGap, y:dragTopic.getPosition().y};
|
||||
|
||||
// Perform a initial filter to discard topics:
|
||||
// - Exclude dragged topic
|
||||
// - Exclude dragTopic pivot
|
||||
// - Nodes that are collapsed
|
||||
// - It's not part of the branch dragged itself
|
||||
topics = topics.filter(function (topic) {
|
||||
var result = draggedNode != topic;
|
||||
result = result && topic != draggedNode;
|
||||
result = result && !topic.areChildrenShrunken() && !topic.isCollapsed();
|
||||
result = result && !draggedNode.isChildTopic(topic);
|
||||
return result;
|
||||
});
|
||||
|
||||
// Filter all the nodes that are outside the vertical boundary:
|
||||
// * The node is to out of the x scope
|
||||
// * The x distance greater the vertical tolerated distance
|
||||
topics = topics.filter(function (topic) {
|
||||
var tpos = topic.getPosition();
|
||||
// Center topic has different alignment than the rest of the nodes. That's why i need to divide it by two...
|
||||
var txborder = tpos.x + (topic.getSize().width / 2) * Math.sign(sPos.x);
|
||||
var distance = (sPos.x - txborder) * Math.sign(sPos.x);
|
||||
return distance > 0 && (distance < mindplot.DragConnector.MAX_VERTICAL_CONNECTION_TOLERANCE);
|
||||
|
||||
});
|
||||
|
||||
// Assign a priority based on the distance:
|
||||
// - Alignment with the targetNode
|
||||
// - Vertical distance
|
||||
// - Horizontal proximity
|
||||
// - It's already connected.
|
||||
var currentConnection = dragTopic.getConnectedToTopic();
|
||||
var me = this;
|
||||
topics = topics.sort(function (a, b) {
|
||||
var aPos = a.getPosition();
|
||||
var bPos = b.getPosition();
|
||||
|
||||
var av = me._isVerticallyAligned(a.getSize(), aPos, sPos);
|
||||
var bv = me._isVerticallyAligned(b.getSize(), bPos, sPos);
|
||||
return me._proximityWeight(av, a, sPos, currentConnection) - me._proximityWeight(bv, b, sPos, currentConnection);
|
||||
|
||||
});
|
||||
return topics;
|
||||
},
|
||||
|
||||
_proximityWeight:function (isAligned, target, sPos, currentConnection) {
|
||||
var tPos = target.getPosition();
|
||||
return (isAligned ? 0 : 200 ) + Math.abs(tPos.x - sPos.x) + Math.abs(tPos.y - sPos.y) + (currentConnection == target ? 0 : 100);
|
||||
},
|
||||
|
||||
_isVerticallyAligned:function (targetSize, targetPosition, sourcePosition) {
|
||||
|
||||
return Math.abs(sourcePosition.y - targetPosition.y) < targetSize.height / 2;
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
mindplot.DragConnector.MAX_VERTICAL_CONNECTION_TOLERANCE = 80;
|
@ -1,148 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.DragManager = new Class({
|
||||
initialize:function(workspace, eventDispatcher) {
|
||||
this._workspace = workspace;
|
||||
this._designerModel = workspace;
|
||||
this._listeners = {};
|
||||
this._isDragInProcess = false;
|
||||
this._eventDispatcher = eventDispatcher;
|
||||
mindplot.DragTopic.init(this._workspace);
|
||||
},
|
||||
|
||||
add : function(node) {
|
||||
// Add behaviour ...
|
||||
var workspace = this._workspace;
|
||||
var screen = workspace.getScreenManager();
|
||||
var dragManager = this;
|
||||
var me = this;
|
||||
var mouseDownListener = function(event) {
|
||||
if (workspace.isWorkspaceEventsEnabled()) {
|
||||
// Disable double drag...
|
||||
workspace.enableWorkspaceEvents(false);
|
||||
|
||||
// Set initial position.
|
||||
var layoutManager = me._eventDispatcher.getLayoutManager();
|
||||
var dragNode = node.createDragNode(layoutManager);
|
||||
|
||||
// Register mouse move listener ...
|
||||
var mouseMoveListener = dragManager._buildMouseMoveListener(workspace, dragNode, dragManager);
|
||||
screen.addEvent('mousemove', mouseMoveListener);
|
||||
|
||||
// Register mouse up listeners ...
|
||||
var mouseUpListener = dragManager._buildMouseUpListener(workspace, node, dragNode, dragManager);
|
||||
screen.addEvent('mouseup', mouseUpListener);
|
||||
|
||||
// Change cursor.
|
||||
window.document.body.style.cursor = 'move';
|
||||
}
|
||||
};
|
||||
node.addEvent('mousedown', mouseDownListener);
|
||||
},
|
||||
|
||||
remove : function(node) {
|
||||
var nodes = this._topics;
|
||||
var contained = false;
|
||||
var index = -1;
|
||||
for (var i = 0; i < nodes.length; i++) {
|
||||
if (nodes[i] == node) {
|
||||
contained = true;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_buildMouseMoveListener : function(workspace, dragNode, dragManager) {
|
||||
var screen = workspace.getScreenManager();
|
||||
var me = this;
|
||||
var result = function(event) {
|
||||
|
||||
if (!me._isDragInProcess) {
|
||||
// Execute Listeners ..
|
||||
var startDragListener = dragManager._listeners['startdragging'];
|
||||
startDragListener(event, dragNode);
|
||||
|
||||
// Add shadow node to the workspace.
|
||||
workspace.append(dragNode);
|
||||
|
||||
me._isDragInProcess = true;
|
||||
}
|
||||
|
||||
var pos = screen.getWorkspaceMousePosition(event);
|
||||
dragNode.setPosition(pos.x, pos.y);
|
||||
|
||||
// Call mouse move listeners ...
|
||||
var dragListener = dragManager._listeners['dragging'];
|
||||
if ($defined(dragListener)) {
|
||||
dragListener(event, dragNode);
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
};
|
||||
dragManager._mouseMoveListener = result;
|
||||
return result;
|
||||
},
|
||||
|
||||
_buildMouseUpListener : function(workspace, node, dragNode, dragManager) {
|
||||
var screen = workspace.getScreenManager();
|
||||
var me = this;
|
||||
var result = function(event) {
|
||||
$assert(dragNode.isDragTopic, 'dragNode must be an DragTopic');
|
||||
|
||||
// Remove all the events.
|
||||
screen.removeEvent('mousemove', dragManager._mouseMoveListener);
|
||||
screen.removeEvent('mouseup', dragManager._mouseUpListener);
|
||||
|
||||
// Help GC
|
||||
dragManager._mouseMoveListener = null;
|
||||
dragManager._mouseUpListener = null;
|
||||
|
||||
workspace.enableWorkspaceEvents(true);
|
||||
// Change the cursor to the default.
|
||||
window.document.body.style.cursor = 'default';
|
||||
|
||||
if (me._isDragInProcess) {
|
||||
|
||||
// Execute Listeners only if the node has been moved.
|
||||
var endDragListener = dragManager._listeners['enddragging'];
|
||||
endDragListener(event, dragNode);
|
||||
|
||||
// Remove drag node from the workspace.
|
||||
dragNode.removeFromWorkspace(workspace);
|
||||
|
||||
me._isDragInProcess = false;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
dragManager._mouseUpListener = result;
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* type:
|
||||
* - startdragging.
|
||||
* - dragging
|
||||
* - enddragging
|
||||
*/
|
||||
addEvent : function(type, listener) {
|
||||
this._listeners[type] = listener;
|
||||
}
|
||||
});
|
@ -1,228 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.DragPivot = new Class({
|
||||
initialize:function() {
|
||||
this._position = new core.Point();
|
||||
this._size = mindplot.DragTopic.PIVOT_SIZE;
|
||||
|
||||
this._straightLine = this._buildStraightLine();
|
||||
this._curvedLine = this._buildCurvedLine();
|
||||
this._dragPivot = this._buildRect();
|
||||
this._connectRect = this._buildRect();
|
||||
this._targetTopic = null;
|
||||
this._isVisible = false;
|
||||
},
|
||||
|
||||
isVisible:function() {
|
||||
return this._isVisible;
|
||||
},
|
||||
|
||||
getTargetTopic : function() {
|
||||
return this._targetTopic;
|
||||
},
|
||||
|
||||
_buildStraightLine : function() {
|
||||
var line = new web2d.CurvedLine();
|
||||
line.setStyle(web2d.CurvedLine.SIMPLE_LINE);
|
||||
line.setStroke(1, 'solid', '#CC0033');
|
||||
line.setOpacity(0.4);
|
||||
line.setVisibility(false);
|
||||
return line;
|
||||
},
|
||||
|
||||
_buildCurvedLine : function() {
|
||||
var line = new web2d.CurvedLine();
|
||||
line.setStyle(web2d.CurvedLine.SIMPLE_LINE);
|
||||
line.setStroke(1, 'solid', '#CC0033');
|
||||
line.setOpacity(0.4);
|
||||
line.setVisibility(false);
|
||||
return line;
|
||||
},
|
||||
|
||||
|
||||
_redrawLine : function() {
|
||||
// Update line position.
|
||||
$assert(this.getTargetTopic(), 'Illegal invocation. Target node can not be null');
|
||||
|
||||
var pivotRect = this._getPivotRect();
|
||||
|
||||
// Pivot position has not changed. In this case, position change is not required.
|
||||
var targetTopic = this.getTargetTopic();
|
||||
var position = this._position;
|
||||
|
||||
// Calculate pivot connection point ...
|
||||
var size = this._size;
|
||||
var targetPosition = targetTopic.getPosition();
|
||||
var line = this._getConnectionLine();
|
||||
|
||||
// Update Line position.
|
||||
var isAtRight = mindplot.util.Shape.isAtRight(targetPosition, position);
|
||||
var pivotPoint = mindplot.util.Shape.calculateRectConnectionPoint(position, size, isAtRight);
|
||||
line.setFrom(pivotPoint.x, pivotPoint.y);
|
||||
|
||||
// Update rect position
|
||||
var cx = position.x - (parseInt(size.width) / 2);
|
||||
var cy = position.y - (parseInt(size.height) / 2);
|
||||
pivotRect.setPosition(cx, cy);
|
||||
|
||||
// Make line visible only when the position has been already changed.
|
||||
// This solve several strange effects ;)
|
||||
var targetPoint = targetTopic.workoutIncomingConnectionPoint(pivotPoint);
|
||||
line.setTo(targetPoint.x, targetPoint.y);
|
||||
},
|
||||
|
||||
setPosition : function(point) {
|
||||
this._position = point;
|
||||
this._redrawLine();
|
||||
},
|
||||
|
||||
getPosition : function() {
|
||||
return this._position;
|
||||
},
|
||||
|
||||
_buildRect : function() {
|
||||
var size = this._size;
|
||||
var rectAttributes = {fillColor:'#CC0033',opacity:0.4,width:size.width,height:size.height,strokeColor:'#FF9933'};
|
||||
var rect = new web2d.Rect(0, rectAttributes);
|
||||
rect.setVisibility(false);
|
||||
return rect;
|
||||
},
|
||||
|
||||
_getPivotRect : function() {
|
||||
return this._dragPivot;
|
||||
},
|
||||
|
||||
getSize : function() {
|
||||
var elem2d = this._getPivotRect();
|
||||
return elem2d.getSize();
|
||||
},
|
||||
|
||||
setVisibility : function(value) {
|
||||
if (this.isVisible() != value) {
|
||||
|
||||
var pivotRect = this._getPivotRect();
|
||||
pivotRect.setVisibility(value);
|
||||
|
||||
var connectRect = this._connectRect;
|
||||
connectRect.setVisibility(value);
|
||||
|
||||
var line = this._getConnectionLine();
|
||||
if (line) {
|
||||
line.setVisibility(value);
|
||||
}
|
||||
this._isVisible = value;
|
||||
}
|
||||
},
|
||||
|
||||
// If the node is connected, validate that there is a line connecting both...
|
||||
_getConnectionLine : function() {
|
||||
var result = null;
|
||||
var parentTopic = this._targetTopic;
|
||||
if (parentTopic) {
|
||||
if (parentTopic.getType() == mindplot.model.INodeModel.CENTRAL_TOPIC_TYPE) {
|
||||
result = this._straightLine;
|
||||
} else {
|
||||
result = this._curvedLine;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
addToWorkspace : function(workspace) {
|
||||
var pivotRect = this._getPivotRect();
|
||||
workspace.append(pivotRect);
|
||||
|
||||
var connectToRect = this._connectRect;
|
||||
workspace.append(connectToRect);
|
||||
|
||||
// Add a hidden straight line ...
|
||||
var straighLine = this._straightLine;
|
||||
straighLine.setVisibility(false);
|
||||
workspace.append(straighLine);
|
||||
straighLine.moveToBack();
|
||||
|
||||
// Add a hidden curved line ...
|
||||
var curvedLine = this._curvedLine;
|
||||
curvedLine.setVisibility(false);
|
||||
workspace.append(curvedLine);
|
||||
curvedLine.moveToBack();
|
||||
|
||||
// Add a connect rect ...
|
||||
var connectRect = this._connectRect;
|
||||
connectRect.setVisibility(false);
|
||||
workspace.append(connectRect);
|
||||
connectRect.moveToBack();
|
||||
},
|
||||
|
||||
removeFromWorkspace : function(workspace) {
|
||||
var shape = this._getPivotRect();
|
||||
workspace.removeChild(shape);
|
||||
|
||||
var connectToRect = this._connectRect;
|
||||
workspace.removeChild(connectToRect);
|
||||
|
||||
if ($defined(this._straightLine)) {
|
||||
workspace.removeChild(this._straightLine);
|
||||
}
|
||||
|
||||
if ($defined(this._curvedLine)) {
|
||||
workspace.removeChild(this._curvedLine);
|
||||
}
|
||||
},
|
||||
|
||||
connectTo : function(targetTopic, position) {
|
||||
$assert(!this._outgoingLine, 'Could not connect an already connected node');
|
||||
$assert(targetTopic != this, 'Circular connection are not allowed');
|
||||
$assert(position, 'position can not be null');
|
||||
$assert(targetTopic, 'parent can not be null');
|
||||
|
||||
this._position = position;
|
||||
this._targetTopic = targetTopic;
|
||||
|
||||
// Connected to Rect ...
|
||||
var connectRect = this._connectRect;
|
||||
var targetSize = targetTopic.getSize();
|
||||
|
||||
// Add 4 pixel in order to keep create a rect bigger than the topic.
|
||||
var width = targetSize.width + 4;
|
||||
var height = targetSize.height + 4;
|
||||
|
||||
connectRect.setSize(width, height);
|
||||
|
||||
var targetPosition = targetTopic.getPosition();
|
||||
var cx = Math.ceil(targetPosition.x - (width / 2));
|
||||
var cy = Math.ceil(targetPosition.y - (height / 2));
|
||||
connectRect.setPosition(cx, cy);
|
||||
|
||||
// Change elements position ...
|
||||
var pivotRect = this._getPivotRect();
|
||||
pivotRect.moveToFront();
|
||||
pivotRect.setPosition(position.x, position.y);
|
||||
|
||||
this._redrawLine();
|
||||
},
|
||||
|
||||
disconnect : function(workspace) {
|
||||
$assert(workspace, 'workspace can not be null.');
|
||||
$assert(this._targetTopic, 'There are not connected topic.');
|
||||
|
||||
this.setVisibility(false);
|
||||
this._targetTopic = null;
|
||||
}
|
||||
});
|
@ -1,215 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.DragTopic = new Class({
|
||||
initialize:function (dragShape, draggedNode, layoutManger) {
|
||||
$assert(dragShape, 'Rect can not be null.');
|
||||
$assert(draggedNode, 'draggedNode can not be null.');
|
||||
$assert(layoutManger, 'layoutManger can not be null.');
|
||||
|
||||
this._elem2d = dragShape;
|
||||
this._order = null;
|
||||
this._draggedNode = draggedNode;
|
||||
this._layoutManager = layoutManger;
|
||||
this._position = new core.Point();
|
||||
this._isInWorkspace = false;
|
||||
this._isFreeLayoutEnabled = false;
|
||||
},
|
||||
|
||||
setOrder:function (order) {
|
||||
this._order = order;
|
||||
},
|
||||
|
||||
setPosition:function (x, y) {
|
||||
// Update drag shadow position ....
|
||||
var position = {x:x, y:y};
|
||||
if (this.isFreeLayoutOn() && this.isConnected()) {
|
||||
var _layoutManager = this._layoutManager;
|
||||
var par = this.getConnectedToTopic();
|
||||
position = _layoutManager.predict(par.getId(), this._draggedNode.getId(), position, true).position;
|
||||
}
|
||||
this._position.setValue(position.x, position.y);
|
||||
|
||||
// Elements are positioned in the center.
|
||||
// All topic element must be positioned based on the innerShape.
|
||||
var draggedNode = this._draggedNode;
|
||||
var size = draggedNode.getSize();
|
||||
var cx = position.x - (position.x > 0 ? 0 : size.width);
|
||||
var cy = Math.ceil(position.y - (size.height / 2));
|
||||
this._elem2d.setPosition(cx, cy);
|
||||
|
||||
// In case is not free, pivot must be draw ...
|
||||
if (this.isConnected() && !this.isFreeLayoutOn()) {
|
||||
var parent = this.getConnectedToTopic();
|
||||
var predict = this._layoutManager.predict(parent.getId(), this._draggedNode.getId(), this.getPosition());
|
||||
if (this._order != predict.order) {
|
||||
var dragPivot = this._getDragPivot();
|
||||
var pivotPosition = predict.position;
|
||||
dragPivot.connectTo(parent, pivotPosition);
|
||||
this.setOrder(predict.order);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
updateFreeLayout:function (event) {
|
||||
var isFreeEnabled = (event.metaKey && Browser.Platform.mac) || (event.ctrlKey && !Browser.Platform.mac);
|
||||
if (this.isFreeLayoutOn() != isFreeEnabled) {
|
||||
var dragPivot = this._getDragPivot();
|
||||
dragPivot.setVisibility(!isFreeEnabled);
|
||||
this._isFreeLayoutEnabled = isFreeEnabled;
|
||||
}
|
||||
},
|
||||
|
||||
setVisibility:function (value) {
|
||||
var dragPivot = this._getDragPivot();
|
||||
dragPivot.setVisibility(value);
|
||||
},
|
||||
|
||||
isVisible:function () {
|
||||
var dragPivot = this._getDragPivot();
|
||||
return dragPivot.isVisible();
|
||||
},
|
||||
|
||||
getInnerShape:function () {
|
||||
return this._elem2d;
|
||||
},
|
||||
|
||||
disconnect:function (workspace) {
|
||||
// Clear connection line ...
|
||||
var dragPivot = this._getDragPivot();
|
||||
dragPivot.disconnect(workspace);
|
||||
},
|
||||
|
||||
connectTo:function (parent) {
|
||||
$assert(parent, 'Parent connection node can not be null.');
|
||||
|
||||
// Where it should be connected ?
|
||||
var predict = designer._eventBussDispatcher._layoutManager.predict(parent.getId(), this._draggedNode.getId(), this.getPosition());
|
||||
|
||||
// Connect pivot ...
|
||||
var dragPivot = this._getDragPivot();
|
||||
var position = predict.position;
|
||||
dragPivot.connectTo(parent, position);
|
||||
dragPivot.setVisibility(true);
|
||||
|
||||
this.setOrder(predict.order);
|
||||
},
|
||||
|
||||
getDraggedTopic:function () {
|
||||
return this._draggedNode;
|
||||
},
|
||||
|
||||
removeFromWorkspace:function (workspace) {
|
||||
if (this._isInWorkspace) {
|
||||
// Remove drag shadow.
|
||||
workspace.removeChild(this._elem2d);
|
||||
|
||||
// Remove pivot shape. To improve performance it will not be removed. Only the visibility will be changed.
|
||||
var dragPivot = this._getDragPivot();
|
||||
dragPivot.setVisibility(false);
|
||||
|
||||
this._isInWorkspace = false;
|
||||
}
|
||||
},
|
||||
|
||||
isInWorkspace:function () {
|
||||
return this._isInWorkspace;
|
||||
},
|
||||
|
||||
addToWorkspace:function (workspace) {
|
||||
if (!this._isInWorkspace) {
|
||||
workspace.append(this._elem2d);
|
||||
var dragPivot = this._getDragPivot();
|
||||
dragPivot.addToWorkspace(workspace);
|
||||
this._isInWorkspace = true;
|
||||
}
|
||||
},
|
||||
|
||||
_getDragPivot:function () {
|
||||
return mindplot.DragTopic.__getDragPivot();
|
||||
},
|
||||
|
||||
getPosition:function () {
|
||||
return this._position;
|
||||
},
|
||||
|
||||
isDragTopic:function () {
|
||||
return true;
|
||||
},
|
||||
|
||||
applyChanges:function (workspace) {
|
||||
$assert(workspace, 'workspace can not be null');
|
||||
|
||||
|
||||
var actionDispatcher = mindplot.ActionDispatcher.getInstance();
|
||||
var draggedTopic = this.getDraggedTopic();
|
||||
var topicId = draggedTopic.getId();
|
||||
var position = this.getPosition();
|
||||
|
||||
if (!this.isFreeLayoutOn()) {
|
||||
var order = null;
|
||||
var parent = null;
|
||||
var isDragConnected = this.isConnected();
|
||||
if (isDragConnected) {
|
||||
var targetTopic = this.getConnectedToTopic();
|
||||
order = this._order;
|
||||
parent = targetTopic;
|
||||
}
|
||||
|
||||
// If the node is not connected, position based on the original drag topic position.
|
||||
actionDispatcher.dragTopic(topicId, position, order, parent);
|
||||
} else {
|
||||
actionDispatcher.moveTopic(topicId, position);
|
||||
}
|
||||
},
|
||||
|
||||
getConnectedToTopic:function () {
|
||||
var dragPivot = this._getDragPivot();
|
||||
return dragPivot.getTargetTopic();
|
||||
},
|
||||
|
||||
isConnected:function () {
|
||||
return this.getConnectedToTopic() != null;
|
||||
},
|
||||
|
||||
isFreeLayoutOn:function () {
|
||||
// return this._isFreeLayoutEnabled;
|
||||
// Disable free layout ...
|
||||
return false;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
mindplot.DragTopic.PIVOT_SIZE = {width:50, height:6};
|
||||
|
||||
mindplot.DragTopic.init = function (workspace) {
|
||||
|
||||
$assert(workspace, "workspace can not be null");
|
||||
var pivot = mindplot.DragTopic.__getDragPivot();
|
||||
workspace.append(pivot);
|
||||
};
|
||||
|
||||
mindplot.DragTopic.__getDragPivot = function () {
|
||||
var result = mindplot.DragTopic._dragPivot;
|
||||
if (!$defined(result)) {
|
||||
result = new mindplot.DragPivot();
|
||||
mindplot.DragTopic._dragPivot = result;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.EditorOptions =
|
||||
{
|
||||
LayoutManager:"OriginalLayout",
|
||||
// LayoutManager:"FreeMindLayout",
|
||||
textEditor:"TextEditor"
|
||||
// textEditor:"RichTextEditor"
|
||||
};
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.EditorProperties = new Class({
|
||||
initialize: function () {
|
||||
this._zoom = 0;
|
||||
this._position = 0;
|
||||
},
|
||||
|
||||
setZoom: function (zoom) {
|
||||
this._zoom = zoom;
|
||||
},
|
||||
|
||||
getZoom: function () {
|
||||
return this._zoom;
|
||||
},
|
||||
|
||||
asProperties: function () {
|
||||
return "zoom=" + this._zoom + "\n";
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
@ -1,41 +0,0 @@
|
||||
mindplot.Events = new Class({
|
||||
|
||||
$events: {},
|
||||
|
||||
_removeOn: function (string) {
|
||||
return string.replace(/^on([A-Z])/, function (full, first) {
|
||||
return first.toLowerCase();
|
||||
});
|
||||
},
|
||||
|
||||
addEvent: function (type, fn, internal) {
|
||||
type = this._removeOn(type);
|
||||
|
||||
this.$events[type] = (this.$events[type] || []).include(fn);
|
||||
if (internal) fn.internal = true;
|
||||
return this;
|
||||
},
|
||||
|
||||
fireEvent: function (type, args, delay) {
|
||||
type = this._removeOn(type);
|
||||
var events = this.$events[type];
|
||||
if (!events) return this;
|
||||
args = Array.from(args);
|
||||
_.each(events, function (fn) {
|
||||
if (delay) fn.delay(delay, this, args);
|
||||
else fn.apply(this, args);
|
||||
}, this);
|
||||
return this;
|
||||
},
|
||||
|
||||
removeEvent: function (type, fn) {
|
||||
type = this._removeOn(type);
|
||||
var events = this.$events[type];
|
||||
if (events && !fn.internal) {
|
||||
var index = events.indexOf(fn);
|
||||
if (index != -1) events.splice(index, 1);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
});
|
@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.Icon = new Class({
|
||||
initialize: function (url) {
|
||||
$assert(url, 'topic can not be null');
|
||||
this._image = new web2d.Image();
|
||||
this._image.setHref(url);
|
||||
this._image.setSize(mindplot.Icon.SIZE, mindplot.Icon.SIZE);
|
||||
},
|
||||
|
||||
getImage: function () {
|
||||
return this._image;
|
||||
},
|
||||
|
||||
setGroup: function (group) {
|
||||
this._group = group;
|
||||
},
|
||||
|
||||
getGroup: function () {
|
||||
return this._group;
|
||||
},
|
||||
|
||||
getSize: function () {
|
||||
return this._image.getSize();
|
||||
},
|
||||
|
||||
getPosition: function () {
|
||||
return this._image.getPosition();
|
||||
},
|
||||
|
||||
addEvent: function (type, fnc) {
|
||||
this._image.addEvent(type, fnc);
|
||||
},
|
||||
|
||||
remove: function () {
|
||||
throw "Unsupported operation";
|
||||
}
|
||||
});
|
||||
|
||||
mindplot.Icon.SIZE = 90;
|
||||
|
||||
|
||||
|
||||
|
@ -1,340 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.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");
|
||||
|
||||
this._icons = [];
|
||||
this._group = new web2d.Group({
|
||||
width: 0,
|
||||
height: iconSize,
|
||||
x: 0,
|
||||
y: 0,
|
||||
coordSizeWidth: 0,
|
||||
coordSizeHeight: 100
|
||||
});
|
||||
this._removeTip = new mindplot.IconGroup.RemoveTip(this._group, topicId);
|
||||
this.seIconSize(iconSize, iconSize);
|
||||
|
||||
this._registerListeners();
|
||||
|
||||
},
|
||||
|
||||
/** */
|
||||
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");
|
||||
|
||||
icon.setGroup(this);
|
||||
this._icons.push(icon);
|
||||
|
||||
// Adjust group and position ...
|
||||
this._resize(this._icons.length);
|
||||
this._positionIcon(icon, this._icons.length - 1);
|
||||
|
||||
var imageShape = icon.getImage();
|
||||
this._group.append(imageShape);
|
||||
|
||||
// Register event for the group ..
|
||||
if (remove) {
|
||||
this._removeTip.decorate(this._topicId, icon);
|
||||
}
|
||||
},
|
||||
|
||||
_findIconFromModel: function (iconModel) {
|
||||
var result = null;
|
||||
_.each(this._icons, function (icon) {
|
||||
var elModel = icon.getModel();
|
||||
if (elModel.getId() == iconModel.getId()) {
|
||||
result = icon;
|
||||
}
|
||||
}, this);
|
||||
|
||||
if (result == null) {
|
||||
throw new Error("Icon can no be found:" + iconModel.getId() + ", Icons:" + this._icons);
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
/** */
|
||||
removeIconByModel: function (featureModel) {
|
||||
$assert(featureModel, "featureModel can not be null");
|
||||
|
||||
var icon = this._findIconFromModel(featureModel);
|
||||
this._removeIcon(icon);
|
||||
},
|
||||
|
||||
_removeIcon: function (icon) {
|
||||
$assert(icon, "icon can not be null");
|
||||
|
||||
this._removeTip.close(0);
|
||||
this._group.removeChild(icon.getImage());
|
||||
|
||||
this._icons.erase(icon);
|
||||
this._resize(this._icons.length);
|
||||
var me = this;
|
||||
// Add all again ...
|
||||
_.each(this._icons, function (elem, i) {
|
||||
me._positionIcon(elem, i);
|
||||
});
|
||||
},
|
||||
|
||||
/** */
|
||||
moveToFront: function () {
|
||||
this._group.moveToFront();
|
||||
},
|
||||
|
||||
_registerListeners: function () {
|
||||
this._group.addEvent('click', function (event) {
|
||||
// Avoid node creation ...
|
||||
event.stopPropagation();
|
||||
|
||||
});
|
||||
|
||||
this._group.addEvent('dblclick', function (event) {
|
||||
event.stopPropagation();
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
_resize: function (iconsLength) {
|
||||
this._group.setSize(iconsLength * this._iconSize.width, this._iconSize.height);
|
||||
|
||||
var iconSize = mindplot.Icon.SIZE + (mindplot.IconGroup.ICON_PADDING * 2);
|
||||
this._group.setCoordSize(iconsLength * iconSize, iconSize);
|
||||
},
|
||||
|
||||
_positionIcon: function (icon, order) {
|
||||
|
||||
var iconSize = mindplot.Icon.SIZE + (mindplot.IconGroup.ICON_PADDING * 2);
|
||||
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(/** @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');
|
||||
|
||||
// Nothing to do ...
|
||||
if (this._activeIcon != icon) {
|
||||
// If there is an active icon, close it first ...
|
||||
if (this._activeIcon) {
|
||||
this.close(0);
|
||||
}
|
||||
|
||||
// Now, let move the position the icon...
|
||||
var pos = icon.getPosition();
|
||||
|
||||
// Register events ...
|
||||
var widget = this._buildWeb2d();
|
||||
widget.addEvent('click', function () {
|
||||
icon.remove();
|
||||
});
|
||||
|
||||
var me = this;
|
||||
|
||||
widget.addEvent('mouseover', function () {
|
||||
me.show(topicId, icon);
|
||||
});
|
||||
|
||||
widget.addEvent('mouseout', function () {
|
||||
me.hide();
|
||||
});
|
||||
|
||||
widget.setPosition(pos.x + 80, pos.y - 50);
|
||||
this._fadeElem.append(widget);
|
||||
|
||||
// Setup current element ...
|
||||
this._activeIcon = icon;
|
||||
this._widget = widget;
|
||||
|
||||
} else {
|
||||
clearTimeout(this._closeTimeoutId);
|
||||
}
|
||||
},
|
||||
|
||||
/** */
|
||||
hide: function () {
|
||||
this.close(200);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param delay
|
||||
*/
|
||||
close: function (delay) {
|
||||
|
||||
// This is not ok, trying to close the same dialog twice ?
|
||||
if (this._closeTimeoutId) {
|
||||
clearTimeout(this._closeTimeoutId)
|
||||
}
|
||||
|
||||
var me = this;
|
||||
if (this._activeIcon) {
|
||||
var widget = this._widget;
|
||||
var close = function () {
|
||||
me._activeIcon = null;
|
||||
me._fadeElem.removeChild(widget);
|
||||
me._widget = null;
|
||||
me._closeTimeoutId = null;
|
||||
};
|
||||
|
||||
if (!$defined(delay) || delay == 0) {
|
||||
close();
|
||||
}
|
||||
else {
|
||||
this._closeTimeoutId = close.delay(delay);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_buildWeb2d: function () {
|
||||
var result = new web2d.Group({
|
||||
width: 10,
|
||||
height: 10,
|
||||
x: 0,
|
||||
y: 0,
|
||||
coordSizeWidth: 10,
|
||||
coordSizeHeight: 10
|
||||
});
|
||||
|
||||
var outerRect = new web2d.Rect(0, {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 10,
|
||||
height: 10,
|
||||
stroke: '0',
|
||||
fillColor: 'black'
|
||||
});
|
||||
result.append(outerRect);
|
||||
outerRect.setCursor('pointer');
|
||||
|
||||
var innerRect = new web2d.Rect(0, {
|
||||
x: 1,
|
||||
y: 1,
|
||||
width: 8,
|
||||
height: 8,
|
||||
stroke: '1 solid white',
|
||||
fillColor: 'gray'
|
||||
});
|
||||
result.append(innerRect);
|
||||
|
||||
var line = new web2d.Line({stroke: '1 solid white'});
|
||||
line.setFrom(1, 1);
|
||||
line.setTo(9, 9);
|
||||
result.append(line);
|
||||
|
||||
var line2 = new web2d.Line({stroke: '1 solid white'});
|
||||
line2.setFrom(1, 9);
|
||||
line2.setTo(9, 1);
|
||||
result.append(line2);
|
||||
|
||||
// Some events ...
|
||||
result.addEvent('mouseover', function () {
|
||||
innerRect.setFill('#CC0033');
|
||||
});
|
||||
result.addEvent('mouseout', function () {
|
||||
innerRect.setFill('gray');
|
||||
});
|
||||
|
||||
result.setSize(50, 50);
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param topicId
|
||||
* @param icon
|
||||
*/
|
||||
decorate: function (topicId, icon) {
|
||||
|
||||
var me = this;
|
||||
|
||||
if (!icon.__remove) {
|
||||
icon.addEvent('mouseover', function () {
|
||||
me.show(topicId, icon);
|
||||
});
|
||||
|
||||
icon.addEvent('mouseout', function () {
|
||||
me.hide();
|
||||
});
|
||||
icon.__remove = true;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
@ -1,163 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.ImageIcon = new Class({
|
||||
Extends: mindplot.Icon,
|
||||
initialize: function (topic, iconModel, readOnly) {
|
||||
$assert(iconModel, 'iconModel can not be null');
|
||||
$assert(topic, 'topic can not be null');
|
||||
|
||||
this._topicId = topic.getId();
|
||||
this._featureModel = iconModel;
|
||||
|
||||
// Build graph image representation ...
|
||||
var iconType = iconModel.getIconType();
|
||||
var imgUrl = this._getImageUrl(iconType);
|
||||
this.parent(imgUrl);
|
||||
|
||||
if (!readOnly) {
|
||||
|
||||
//Icon
|
||||
var image = this.getImage();
|
||||
var me = this;
|
||||
image.addEvent('click', function () {
|
||||
|
||||
var iconType = iconModel.getIconType();
|
||||
var newIconType = me._getNextFamilyIconId(iconType);
|
||||
iconModel.setIconType(newIconType);
|
||||
|
||||
var imgUrl = me._getImageUrl(newIconType);
|
||||
me._image.setHref(imgUrl);
|
||||
|
||||
});
|
||||
this._image.setCursor('pointer');
|
||||
}
|
||||
},
|
||||
|
||||
_getImageUrl: function (iconId) {
|
||||
return "icons/" + iconId + ".png";
|
||||
},
|
||||
|
||||
getModel: function () {
|
||||
return this._featureModel;
|
||||
},
|
||||
|
||||
_getNextFamilyIconId: function (iconId) {
|
||||
|
||||
var familyIcons = this._getFamilyIcons(iconId);
|
||||
$assert(familyIcons != null, "Family Icon not found!");
|
||||
|
||||
var result = null;
|
||||
for (var i = 0; i < familyIcons.length && result == null; i++) {
|
||||
if (familyIcons[i] == iconId) {
|
||||
//Is last one?
|
||||
if (i == (familyIcons.length - 1)) {
|
||||
result = familyIcons[0];
|
||||
} else {
|
||||
result = familyIcons[i + 1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
_getFamilyIcons: function (iconId) {
|
||||
$assert(iconId != null, "id must not be null");
|
||||
$assert(iconId.indexOf("_") != -1, "Invalid icon id (it must contain '_')");
|
||||
|
||||
var result = null;
|
||||
for (var i = 0; i < mindplot.ImageIcon.prototype.ICON_FAMILIES.length; i++) {
|
||||
var family = mindplot.ImageIcon.prototype.ICON_FAMILIES[i];
|
||||
var iconFamilyId = iconId.substr(0, iconId.indexOf("_"));
|
||||
|
||||
if (family.id == iconFamilyId) {
|
||||
result = family.icons;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
remove: function () {
|
||||
var actionDispatcher = mindplot.ActionDispatcher.getInstance();
|
||||
var featureId = this._featureModel.getId();
|
||||
var topicId = this._topicId;
|
||||
actionDispatcher.removeFeatureFromTopic(topicId, featureId);
|
||||
}
|
||||
});
|
||||
|
||||
mindplot.ImageIcon.prototype.ICON_FAMILIES = [
|
||||
{"id": "face", "icons": ["face_plain", "face_sad", "face_crying", "face_smile", "face_surprise", "face_wink"]},
|
||||
{"id": "funy", "icons": ["funy_angel", "funy_devilish", "funy_glasses", "funy_grin", "funy_kiss", "funy_monkey"]},
|
||||
{"id": "conn", "icons": ["conn_connect", "conn_disconnect"]},
|
||||
{
|
||||
"id": "sport",
|
||||
"icons": ["sport_basketball", "sport_football", "sport_golf", "sport_raquet", "sport_shuttlecock", "sport_soccer", "sport_tennis"]
|
||||
},
|
||||
{"id": "bulb", "icons": ["bulb_light_on", "bulb_light_off"]},
|
||||
{"id": "thumb", "icons": ["thumb_thumb_up", "thumb_thumb_down"]},
|
||||
{"id": "tick", "icons": ["tick_tick", "tick_cross"]},
|
||||
{
|
||||
"id": "onoff",
|
||||
"icons": ["onoff_clock", "onoff_clock_red", "onoff_add", "onoff_delete", "onoff_status_offline", "onoff_status_online"]
|
||||
},
|
||||
{
|
||||
"id": "money",
|
||||
"icons": ["money_money", "money_dollar", "money_euro", "money_pound", "money_yen", "money_coins", "money_ruby"]
|
||||
},
|
||||
{"id": "time", "icons": ["time_calendar", "time_clock", "time_hourglass"]},
|
||||
{
|
||||
"id": "number",
|
||||
"icons": ["number_1", "number_2", "number_3", "number_4", "number_5", "number_6", "number_7", "number_8", "number_9"]
|
||||
},
|
||||
{"id": "chart", "icons": ["chart_bar", "chart_line", "chart_curve", "chart_pie", "chart_organisation"]},
|
||||
{"id": "sign", "icons": ["sign_warning", "sign_info", "sign_stop", "sign_help", "sign_cancel"]},
|
||||
{
|
||||
"id": "hard",
|
||||
"icons": ["hard_cd", "hard_computer", "hard_controller", "hard_driver_disk", "hard_ipod", "hard_keyboard", "hard_mouse", "hard_printer"]
|
||||
},
|
||||
{
|
||||
"id": "soft",
|
||||
"icons": ["soft_bug", "soft_cursor", "soft_database_table", "soft_database", "soft_feed", "soft_folder_explore", "soft_rss", "soft_penguin"]
|
||||
},
|
||||
{"id": "arrow", "icons": ["arrow_up", "arrow_down", "arrow_left", "arrow_right"]},
|
||||
{
|
||||
"id": "arrowc",
|
||||
"icons": ["arrowc_rotate_anticlockwise", "arrowc_rotate_clockwise", "arrowc_turn_left", "arrowc_turn_right"]
|
||||
},
|
||||
{"id": "people", "icons": ["people_group", "people_male1", "people_male2", "people_female1", "people_female2"]},
|
||||
{"id": "mail", "icons": ["mail_envelop", "mail_mailbox", "mail_edit", "mail_list"]},
|
||||
{"id": "flag", "icons": ["flag_blue", "flag_green", "flag_orange", "flag_pink", "flag_purple", "flag_yellow"]},
|
||||
{
|
||||
"id": "bullet",
|
||||
"icons": ["bullet_black", "bullet_blue", "bullet_green", "bullet_orange", "bullet_red", "bullet_pink", "bullet_purple"]
|
||||
},
|
||||
{"id": "tag", "icons": ["tag_blue", "tag_green", "tag_orange", "tag_red", "tag_pink", "tag_yellow"]},
|
||||
{
|
||||
"id": "object",
|
||||
"icons": ["object_bell", "object_clanbomber", "object_key", "object_pencil", "object_phone", "object_magnifier", "object_clip", "object_music", "object_star", "object_wizard", "object_house", "object_cake", "object_camera", "object_palette", "object_rainbow"]
|
||||
},
|
||||
{
|
||||
"id": "weather",
|
||||
"icons": ["weather_clear-night", "weather_clear", "weather_few-clouds-night", "weather_few-clouds", "weather_overcast", "weather_severe-alert", "weather_showers-scattered", "weather_showers", "weather_snow", "weather_storm"]
|
||||
},
|
||||
{"id": "task", "icons": ["task_0", "task_25", "task_50", "task_75", "task_100"]}
|
||||
];
|
||||
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.Keyboard = new Class({
|
||||
|
||||
initialize: function () {
|
||||
},
|
||||
|
||||
addShortcut: function (shortcuts, callback) {
|
||||
if (!$.isArray(shortcuts)) {
|
||||
shortcuts = [shortcuts];
|
||||
}
|
||||
_.each(shortcuts, function (shortcut) {
|
||||
$(document).bind('keydown', shortcut, callback);
|
||||
});
|
||||
}
|
||||
|
||||
});
|
@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.LinkIcon = new Class({
|
||||
|
||||
Extends: mindplot.Icon,
|
||||
initialize: function (topic, linkModel, readOnly) {
|
||||
$assert(topic, 'topic can not be null');
|
||||
$assert(linkModel, 'linkModel can not be null');
|
||||
|
||||
this.parent(mindplot.LinkIcon.IMAGE_URL);
|
||||
this._linksModel = linkModel;
|
||||
this._topic = topic;
|
||||
this._readOnly = readOnly;
|
||||
|
||||
this._registerEvents();
|
||||
},
|
||||
|
||||
_registerEvents: function () {
|
||||
this._image.setCursor('pointer');
|
||||
this._tip = new mindplot.widget.LinkIconTooltip(this);
|
||||
|
||||
var me = this;
|
||||
if (!this._readOnly) {
|
||||
// Add on click event to open the editor ...
|
||||
this.addEvent('click', function (event) {
|
||||
me._tip.hide();
|
||||
me._topic.showLinkEditor();
|
||||
event.stopPropagation();
|
||||
});
|
||||
//FIXME: we shouldn't have timeout of that..
|
||||
this.addEvent("mouseleave", function (event) {
|
||||
window.setTimeout(function () {
|
||||
if (!$("#linkPopover:hover").length) {
|
||||
me._tip.hide();
|
||||
}
|
||||
event.stopPropagation();
|
||||
}, 100)
|
||||
});
|
||||
}
|
||||
|
||||
$(this.getImage()._peer._native).mouseenter(function () {
|
||||
me._tip.show();
|
||||
})
|
||||
},
|
||||
|
||||
getModel: function () {
|
||||
return this._linksModel;
|
||||
}
|
||||
});
|
||||
mindplot.LinkIcon.IMAGE_URL = "images/links.png";
|
||||
|
||||
|
@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.LocalStorageManager = new Class({
|
||||
Extends: mindplot.PersistenceManager,
|
||||
initialize: function (documentUrl, forceLoad) {
|
||||
this.parent();
|
||||
this.documentUrl = documentUrl;
|
||||
this.forceLoad = forceLoad;
|
||||
},
|
||||
|
||||
saveMapXml: function (mapId, mapXml, pref, saveHistory, events) {
|
||||
localStorage.setItem(mapId + "-xml", mapXml);
|
||||
},
|
||||
|
||||
discardChanges: function (mapId) {
|
||||
localStorage.removeItem(mapId + "-xml");
|
||||
},
|
||||
|
||||
loadMapDom: function (mapId) {
|
||||
var xml = localStorage.getItem(mapId + "-xml");
|
||||
if (xml == null || this.forceLoad) {
|
||||
$.ajax({
|
||||
url: this.documentUrl.replace("{id}", mapId),
|
||||
headers: {"Content-Type": "text/plain", "Accept": "application/xml"},
|
||||
type: 'get',
|
||||
dataType: "text",
|
||||
async: false,
|
||||
success: function (response) {
|
||||
xml = response;
|
||||
}
|
||||
});
|
||||
// If I could not load it from a file, hard code one.
|
||||
if (xml == null) {
|
||||
throw new Error("Map could not be loaded");
|
||||
}
|
||||
}
|
||||
|
||||
return jQuery.parseXML(xml);
|
||||
},
|
||||
|
||||
unlockMap: function (mindmap) {
|
||||
// Ignore, no implementation required ...
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -1,152 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.MainTopic = new Class(/** @lends MainTopic */{
|
||||
Extends: mindplot.Topic,
|
||||
/**
|
||||
* @extends mindplot.Topic
|
||||
* @constructs
|
||||
* @param model
|
||||
* @param options
|
||||
*/
|
||||
initialize: function (model, options) {
|
||||
this.parent(model, options);
|
||||
},
|
||||
|
||||
INNER_RECT_ATTRIBUTES: {stroke: '0.5 solid #009900'},
|
||||
|
||||
_buildDragShape: function () {
|
||||
var innerShape = this._buildShape(this.INNER_RECT_ATTRIBUTES, this.getShapeType());
|
||||
var size = this.getSize();
|
||||
innerShape.setSize(size.width, size.height);
|
||||
innerShape.setPosition(0, 0);
|
||||
innerShape.setOpacity(0.5);
|
||||
innerShape.setCursor('default');
|
||||
innerShape.setVisibility(true);
|
||||
|
||||
var brColor = this.getBorderColor();
|
||||
innerShape.setAttribute("strokeColor", brColor);
|
||||
|
||||
var bgColor = this.getBackgroundColor();
|
||||
innerShape.setAttribute("fillColor", bgColor);
|
||||
|
||||
// Create group ...
|
||||
var groupAttributes = {width: 100, height: 100, coordSizeWidth: 100, coordSizeHeight: 100};
|
||||
var group = new web2d.Group(groupAttributes);
|
||||
group.append(innerShape);
|
||||
|
||||
// Add Text ...
|
||||
if (this.getShapeType() != mindplot.model.TopicShape.IMAGE) {
|
||||
var textShape = this._buildTextShape(true);
|
||||
var text = this.getText();
|
||||
textShape.setText(text);
|
||||
textShape.setOpacity(0.5);
|
||||
group.append(textShape);
|
||||
}
|
||||
return group;
|
||||
},
|
||||
|
||||
/** */
|
||||
updateTopicShape: function (targetTopic, workspace) {
|
||||
// Change figure based on the connected topic ...
|
||||
var model = this.getModel();
|
||||
var shapeType = model.getShapeType();
|
||||
if (!targetTopic.isCentralTopic()) {
|
||||
if (!$defined(shapeType)) {
|
||||
// Get the real shape type ...
|
||||
shapeType = this.getShapeType();
|
||||
this._setShapeType(shapeType, false);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/** */
|
||||
disconnect: function (workspace) {
|
||||
this.parent(workspace);
|
||||
var size = this.getSize();
|
||||
|
||||
var model = this.getModel();
|
||||
var shapeType = model.getShapeType();
|
||||
if (!$defined(shapeType)) {
|
||||
// Change figure ...
|
||||
shapeType = this.getShapeType();
|
||||
this._setShapeType(mindplot.model.TopicShape.ROUNDED_RECT, false);
|
||||
}
|
||||
var innerShape = this.getInnerShape();
|
||||
innerShape.setVisibility(true);
|
||||
},
|
||||
|
||||
_updatePositionOnChangeSize: function (oldSize, newSize) {
|
||||
|
||||
var xOffset = Math.round((newSize.width - oldSize.width) / 2);
|
||||
var pos = this.getPosition();
|
||||
if ($defined(pos)) {
|
||||
if (pos.x > 0) {
|
||||
pos.x = pos.x + xOffset;
|
||||
} else {
|
||||
pos.x = pos.x - xOffset;
|
||||
}
|
||||
this.setPosition(pos);
|
||||
}
|
||||
},
|
||||
|
||||
/** */
|
||||
workoutIncomingConnectionPoint: function (sourcePosition) {
|
||||
return mindplot.util.Shape.workoutIncomingConnectionPoint(this, sourcePosition);
|
||||
},
|
||||
|
||||
/** */
|
||||
workoutOutgoingConnectionPoint: function (targetPosition) {
|
||||
$assert(targetPosition, 'targetPoint can not be null');
|
||||
var pos = this.getPosition();
|
||||
var isAtRight = mindplot.util.Shape.isAtRight(targetPosition, pos);
|
||||
var size = this.getSize();
|
||||
|
||||
var result;
|
||||
if (this.getShapeType() == mindplot.model.TopicShape.LINE) {
|
||||
|
||||
result = new core.Point();
|
||||
var groupPosition = this._elem2d.getPosition();
|
||||
var innerShareSize = this.getInnerShape().getSize();
|
||||
|
||||
if (innerShareSize) {
|
||||
var magicCorrectionNumber = 0.3;
|
||||
if (!isAtRight) {
|
||||
result.x = groupPosition.x + innerShareSize.width - magicCorrectionNumber;
|
||||
} else {
|
||||
result.x = groupPosition.x + magicCorrectionNumber;
|
||||
}
|
||||
result.y = groupPosition.y + innerShareSize.height;
|
||||
} else {
|
||||
// Hack: When the size has not being defined. This is because the node has not being added.
|
||||
// Try to do our best ...
|
||||
if (!isAtRight) {
|
||||
result.x = pos.x + (size.width / 2);
|
||||
} else {
|
||||
result.x = pos.x - (size.width / 2);
|
||||
}
|
||||
result.y = pos.y + (size.height / 2);
|
||||
}
|
||||
|
||||
} else {
|
||||
result = mindplot.util.Shape.calculateRectConnectionPoint(pos, size, isAtRight, true);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
});
|
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.Messages = new Class({
|
||||
Static: {
|
||||
init: function (locale) {
|
||||
locale = $defined(locale) ? locale : 'en';
|
||||
var bundle = mindplot.Messages.BUNDLES[locale];
|
||||
if (bundle == null && locale.indexOf("_") != -1) {
|
||||
// Try to locate without the specialization ...
|
||||
locale = locale.substring(0, locale.indexOf("_"));
|
||||
bundle = mindplot.Messages.BUNDLES[locale];
|
||||
}
|
||||
mindplot.Messages.__bundle = bundle;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$msg = function (key) {
|
||||
if (!mindplot.Messages.__bundle) {
|
||||
mindplot.Messages.init('en');
|
||||
}
|
||||
|
||||
var msg = mindplot.Messages.__bundle[key];
|
||||
return msg ? msg : key;
|
||||
};
|
||||
|
||||
mindplot.Messages.BUNDLES = {};
|
||||
|
@ -1,313 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.MultilineTextEditor = new Class({
|
||||
Extends: mindplot.Events,
|
||||
initialize: function () {
|
||||
this._topic = null;
|
||||
this._timeoutId = -1;
|
||||
},
|
||||
|
||||
_buildEditor: function () {
|
||||
|
||||
var result = $('<div></div>')
|
||||
.attr('id', 'textContainer')
|
||||
.css({
|
||||
display: "none",
|
||||
zIndex: "8",
|
||||
overflow: "hidden",
|
||||
border: "0 none"
|
||||
});
|
||||
|
||||
|
||||
var textareaElem = $('<textarea tabindex="-1" value="" wrap="off" ></textarea>')
|
||||
.css({
|
||||
border: "1px gray dashed",
|
||||
background: "rgba(98, 135, 167, .3)",
|
||||
outline: '0 none',
|
||||
resize: 'none',
|
||||
overflow: "hidden"
|
||||
});
|
||||
|
||||
result.append(textareaElem);
|
||||
return result;
|
||||
},
|
||||
|
||||
_registerEvents: function (containerElem) {
|
||||
var textareaElem = this._getTextareaElem();
|
||||
var me = this;
|
||||
textareaElem.on('keydown', function (event) {
|
||||
switch (jQuery.hotkeys.specialKeys[event.keyCode]) {
|
||||
case 'esc':
|
||||
me.close(false);
|
||||
break;
|
||||
case 'enter':
|
||||
if (event.metaKey || event.ctrlKey) {
|
||||
|
||||
// Add return ...
|
||||
var text = textareaElem.val();
|
||||
var cursorPosition = text.length;
|
||||
if (textareaElem.selectionStart) {
|
||||
cursorPosition = textareaElem.selectionStart;
|
||||
}
|
||||
|
||||
var head = text.substring(0, cursorPosition);
|
||||
var tail = "";
|
||||
if (cursorPosition < text.length) {
|
||||
tail = text.substring(cursorPosition, text.length);
|
||||
}
|
||||
textareaElem.val(head + "\n" + tail);
|
||||
|
||||
// Position cursor ...
|
||||
if (textareaElem[0].setSelectionRange) {
|
||||
textareaElem.focus();
|
||||
textareaElem[0].setSelectionRange(cursorPosition + 1, cursorPosition + 1);
|
||||
} else if (textareaElem.createTextRange) {
|
||||
var range = textareaElem.createTextRange();
|
||||
range.moveStart('character', cursorPosition + 1);
|
||||
range.select();
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
me.close(true);
|
||||
}
|
||||
break;
|
||||
case 'tab':
|
||||
event.preventDefault();
|
||||
var start = $(this).get(0).selectionStart;
|
||||
var end = $(this).get(0).selectionEnd;
|
||||
|
||||
// set textarea value to: text before caret + tab + text after caret
|
||||
$(this).val($(this).val().substring(0, start) + "\t" + $(this).val().substring(end));
|
||||
|
||||
// put caret at right position again
|
||||
$(this).get(0).selectionStart = $(this).get(0).selectionEnd = start + 1;
|
||||
break;
|
||||
}
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
textareaElem.on('keypress', function (event) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
textareaElem.on('keyup', function (event) {
|
||||
var text = me._getTextareaElem().val();
|
||||
me.fireEvent('input', [event, text]);
|
||||
me._adjustEditorSize();
|
||||
});
|
||||
|
||||
// If the user clicks on the input, all event must be ignored ...
|
||||
containerElem.on('click', function (event) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
containerElem.on('dblclick', function (event) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
containerElem.on('mousedown', function (event) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
},
|
||||
|
||||
_adjustEditorSize: function () {
|
||||
|
||||
if (this.isVisible()) {
|
||||
var textElem = this._getTextareaElem();
|
||||
|
||||
var lines = textElem.val().split('\n');
|
||||
var maxLineLength = 1;
|
||||
_.each(lines, function (line) {
|
||||
if (maxLineLength < line.length)
|
||||
maxLineLength = line.length;
|
||||
});
|
||||
|
||||
textElem.attr('cols', maxLineLength);
|
||||
textElem.attr('rows', lines.length);
|
||||
|
||||
this._containerElem.css({
|
||||
width: (maxLineLength + 3) + 'em',
|
||||
height: textElem.height()
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
isVisible: function () {
|
||||
return $defined(this._containerElem) && this._containerElem.css('display') == 'block';
|
||||
},
|
||||
|
||||
_updateModel: function () {
|
||||
|
||||
if (this._topic.getText() != this._getText()) {
|
||||
var text = this._getText();
|
||||
var topicId = this._topic.getId();
|
||||
|
||||
var actionDispatcher = mindplot.ActionDispatcher.getInstance();
|
||||
actionDispatcher.changeTextToTopic([topicId], text);
|
||||
}
|
||||
},
|
||||
|
||||
show: function (topic, text) {
|
||||
// Close a previous node editor if it's opened ...
|
||||
if (this._topic) {
|
||||
this.close(false);
|
||||
}
|
||||
|
||||
this._topic = topic;
|
||||
if (!this.isVisible()) {
|
||||
//Create editor ui
|
||||
var containerElem = this._buildEditor();
|
||||
$('body').append(containerElem);
|
||||
|
||||
this._containerElem = containerElem;
|
||||
this._registerEvents(containerElem);
|
||||
this._showEditor(text);
|
||||
}
|
||||
},
|
||||
|
||||
_showEditor: function (defaultText) {
|
||||
|
||||
var topic = this._topic;
|
||||
|
||||
// Hide topic text ...
|
||||
topic.getTextShape().setVisibility(false);
|
||||
|
||||
// Set Editor Style
|
||||
var nodeText = topic.getTextShape();
|
||||
var font = nodeText.getFont();
|
||||
font.size = nodeText.getHtmlFontSize();
|
||||
font.color = nodeText.getColor();
|
||||
this._setStyle(font);
|
||||
var me = this;
|
||||
// Set editor's initial size
|
||||
var displayFunc = function () {
|
||||
// Position the editor and set the size...
|
||||
var textShape = topic.getTextShape();
|
||||
|
||||
me._containerElem.css('display', 'block');
|
||||
|
||||
//FIXME: Im not sure if this is best way...
|
||||
var shapePosition = textShape.getNativePosition();
|
||||
me._containerElem.offset(shapePosition);
|
||||
|
||||
// Set editor's initial text ...
|
||||
var text = $defined(defaultText) ? defaultText : topic.getText();
|
||||
me._setText(text);
|
||||
|
||||
// Set the element focus and select the current text ...
|
||||
var inputElem = me._getTextareaElem();
|
||||
me._positionCursor(inputElem, !$defined(defaultText));
|
||||
|
||||
};
|
||||
|
||||
this._timeoutId = displayFunc.delay(10);
|
||||
},
|
||||
|
||||
_setStyle: function (fontStyle) {
|
||||
var inputField = this._getTextareaElem();
|
||||
if (!$defined(fontStyle.font)) {
|
||||
fontStyle.font = "Arial";
|
||||
}
|
||||
if (!$defined(fontStyle.style)) {
|
||||
fontStyle.style = "normal";
|
||||
}
|
||||
if (!$defined(fontStyle.weight)) {
|
||||
fontStyle.weight = "normal";
|
||||
}
|
||||
if (!$defined(fontStyle.size)) {
|
||||
fontStyle.size = 12;
|
||||
}
|
||||
var style = {
|
||||
fontSize: fontStyle.size + "px",
|
||||
fontFamily: fontStyle.font,
|
||||
fontStyle: fontStyle.style,
|
||||
fontWeight: fontStyle.weight,
|
||||
color: fontStyle.color
|
||||
};
|
||||
inputField.css(style);
|
||||
this._containerElem.css(style);
|
||||
},
|
||||
|
||||
_setText: function (text) {
|
||||
var textareaElem = this._getTextareaElem();
|
||||
textareaElem.val(text);
|
||||
this._adjustEditorSize();
|
||||
},
|
||||
|
||||
_getText: function () {
|
||||
return this._getTextareaElem().val();
|
||||
},
|
||||
|
||||
_getTextareaElem: function () {
|
||||
return this._containerElem.find('textarea');
|
||||
},
|
||||
|
||||
_positionCursor: function (textareaElem, selectText) {
|
||||
textareaElem.focus();
|
||||
var lengh = textareaElem.val().length;
|
||||
if (selectText) {
|
||||
// Mark text as selected ...
|
||||
if (textareaElem.createTextRange) {
|
||||
var rang = textareaElem.createTextRange();
|
||||
rang.select();
|
||||
rang.move("character", lengh);
|
||||
}
|
||||
else {
|
||||
textareaElem[0].setSelectionRange(0, lengh);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Move the cursor to the last character ..
|
||||
if (textareaElem.createTextRange) {
|
||||
var range = textareaElem.createTextRange();
|
||||
range.move("character", lengh);
|
||||
} else {
|
||||
if (Browser.ie11) {
|
||||
textareaElem[0].selectionStart = lengh;
|
||||
textareaElem[0].selectionEnd = lengh;
|
||||
} else {
|
||||
textareaElem.selectionStart = lengh;
|
||||
textareaElem.selectionEnd = lengh;
|
||||
}
|
||||
textareaElem.focus();
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
close: function (update) {
|
||||
if (this.isVisible() && this._topic) {
|
||||
// Update changes ...
|
||||
clearTimeout(this._timeoutId);
|
||||
|
||||
if (!$defined(update) || update) {
|
||||
this._updateModel();
|
||||
}
|
||||
|
||||
// Let make the visible text in the node visible again ...
|
||||
this._topic.getTextShape().setVisibility(true);
|
||||
|
||||
// Remove it form the screen ...
|
||||
this._containerElem.remove();
|
||||
this._containerElem = null;
|
||||
this._timeoutId = -1;
|
||||
}
|
||||
this._topic = null;
|
||||
}
|
||||
});
|
||||
|
@ -1,215 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.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");
|
||||
|
||||
this._options = options;
|
||||
this._mouseEvents = true;
|
||||
this.setModel(nodeModel);
|
||||
this._onFocus = false;
|
||||
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);
|
||||
},
|
||||
|
||||
_set2DElement: function (elem2d) {
|
||||
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) {
|
||||
|
||||
this._onFocus = focus;
|
||||
var outerShape = this.getOuterShape();
|
||||
if (focus) {
|
||||
outerShape.setFill(mindplot.Topic.OUTER_SHAPE_ATTRIBUTES_FOCUS.fillColor);
|
||||
outerShape.setOpacity(1);
|
||||
|
||||
} else {
|
||||
outerShape.setFill(mindplot.Topic.OUTER_SHAPE_ATTRIBUTES.fillColor);
|
||||
outerShape.setOpacity(0);
|
||||
}
|
||||
this.setCursor('move');
|
||||
|
||||
// In any case, always try to hide the editor ...
|
||||
this.closeEditors();
|
||||
|
||||
// Fire event ...
|
||||
this.fireEvent(focus ? 'ontfocus' : 'ontblur', this);
|
||||
|
||||
}
|
||||
},
|
||||
|
||||
/** @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);
|
||||
},
|
||||
|
||||
_buildDragShape: function () {
|
||||
$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');
|
||||
|
||||
var type = nodeModel.getType();
|
||||
$assert(type, 'Node model type can not be null');
|
||||
|
||||
var result;
|
||||
if (type == mindplot.model.INodeModel.CENTRAL_TOPIC_TYPE) {
|
||||
result = new mindplot.CentralTopic(nodeModel, options);
|
||||
} else if (type == mindplot.model.INodeModel.MAIN_TOPIC_TYPE) {
|
||||
result = new mindplot.MainTopic(nodeModel, options);
|
||||
} else {
|
||||
$assert(false, "unsupported node type:" + type);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.NoteIcon = new Class({
|
||||
Extends: mindplot.Icon,
|
||||
initialize: function (topic, noteModel, readOnly) {
|
||||
$assert(topic, 'topic can not be null');
|
||||
|
||||
this.parent(mindplot.NoteIcon.IMAGE_URL);
|
||||
this._linksModel = noteModel;
|
||||
this._topic = topic;
|
||||
this._readOnly = readOnly;
|
||||
|
||||
this._registerEvents();
|
||||
},
|
||||
|
||||
_registerEvents: function () {
|
||||
this._image.setCursor('pointer');
|
||||
var me = this;
|
||||
|
||||
if (!this._readOnly) {
|
||||
// Add on click event to open the editor ...
|
||||
this.addEvent('click', function (event) {
|
||||
me._topic.showNoteEditor();
|
||||
event.stopPropagation();
|
||||
});
|
||||
}
|
||||
this._tip = new mindplot.widget.FloatingTip($(me.getImage()._peer._native), {
|
||||
title: $msg('NOTE'),
|
||||
container: 'body',
|
||||
// Content can also be a function of the target element!
|
||||
content: function () {
|
||||
return me._buildTooltipContent();
|
||||
},
|
||||
html: true,
|
||||
placement: 'bottom',
|
||||
destroyOnExit: true
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
_buildTooltipContent: function () {
|
||||
if ($("body").find("#textPopoverNote").length == 1) {
|
||||
var text = $("body").find("#textPopoverNote");
|
||||
text.text(this._linksModel.getText());
|
||||
} else {
|
||||
var result = $('<div id="textPopoverNote"></div>').css({padding: '5px'});
|
||||
|
||||
var text = $('<div></div>').text(this._linksModel.getText())
|
||||
.css({
|
||||
'white-space': 'pre-wrap',
|
||||
'word-wrap': 'break-word'
|
||||
}
|
||||
);
|
||||
result.append(text);
|
||||
return result;
|
||||
}
|
||||
},
|
||||
|
||||
getModel: function () {
|
||||
return this._linksModel;
|
||||
}
|
||||
});
|
||||
|
||||
mindplot.NoteIcon.IMAGE_URL = "images/notes.png";
|
||||
|
@ -1,13 +0,0 @@
|
||||
Options = new Class({
|
||||
|
||||
setOptions: function () {
|
||||
var options = this.options = Object.merge.apply(null, [{}, this.options].append(arguments));
|
||||
if (this.addEvent) for (var option in options) {
|
||||
if (typeOf(options[option]) != 'function' || !(/^on[A-Z]/).test(option)) continue;
|
||||
this.addEvent(option, options[option]);
|
||||
delete options[option];
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
});
|
@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.PersistenceManager = new Class({
|
||||
Static: {
|
||||
loadFromDom: function (mapId, mapDom) {
|
||||
$assert(mapId, "mapId can not be null");
|
||||
$assert(mapDom, "mapDom can not be null");
|
||||
|
||||
var serializer = mindplot.persistence.XMLSerializerFactory.getSerializerFromDocument(mapDom);
|
||||
return serializer.loadFromDom(mapDom, mapId);
|
||||
}
|
||||
},
|
||||
|
||||
initialize: function () {
|
||||
|
||||
},
|
||||
|
||||
save: function (mindmap, editorProperties, saveHistory, events, sync) {
|
||||
$assert(mindmap, "mindmap can not be null");
|
||||
$assert(editorProperties, "editorProperties can not be null");
|
||||
|
||||
var mapId = mindmap.getId();
|
||||
$assert(mapId, "mapId can not be null");
|
||||
|
||||
var serializer = mindplot.persistence.XMLSerializerFactory.getSerializerFromMindmap(mindmap);
|
||||
var domMap = serializer.toXML(mindmap);
|
||||
var mapXml = core.Utils.innerXML(domMap);
|
||||
|
||||
var pref = JSON.stringify(editorProperties);
|
||||
try {
|
||||
this.saveMapXml(mapId, mapXml, pref, saveHistory, events, sync);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
events.onError(this._buildError());
|
||||
}
|
||||
},
|
||||
|
||||
load: function (mapId) {
|
||||
$assert(mapId, "mapId can not be null");
|
||||
var domDocument = this.loadMapDom(mapId);
|
||||
return mindplot.PersistenceManager.loadFromDom(mapId, domDocument);
|
||||
},
|
||||
|
||||
discardChanges: function (mapId) {
|
||||
throw new Error("Method must be implemented");
|
||||
},
|
||||
|
||||
loadMapDom: function (mapId) {
|
||||
throw new Error("Method must be implemented");
|
||||
},
|
||||
|
||||
saveMapXml: function (mapId, mapXml, pref, saveHistory, events, sync) {
|
||||
throw new Error("Method must be implemented");
|
||||
},
|
||||
|
||||
unlockMap: function (mindmap) {
|
||||
throw new Error("Method must be implemented");
|
||||
}
|
||||
});
|
||||
|
||||
mindplot.PersistenceManager.init = function (instance) {
|
||||
mindplot.PersistenceManager._instance = instance;
|
||||
};
|
||||
|
||||
mindplot.PersistenceManager.getInstance = function () {
|
||||
return mindplot.PersistenceManager._instance;
|
||||
};
|
||||
|
@ -1,330 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
mindplot.Relationship = new Class({
|
||||
Extends: mindplot.ConnectionLine,
|
||||
Static: {
|
||||
getStrokeColor: function () {
|
||||
return '#9b74e6';
|
||||
},
|
||||
type: "Relationship"
|
||||
},
|
||||
initialize: function (sourceNode, targetNode, model) {
|
||||
$assert(sourceNode, "sourceNode can not be null");
|
||||
$assert(targetNode, "targetNode can not be null");
|
||||
|
||||
this.parent(sourceNode, targetNode, model.getLineType());
|
||||
this.setModel(model);
|
||||
|
||||
var strokeColor = mindplot.Relationship.getStrokeColor();
|
||||
|
||||
this._line2d.setIsSrcControlPointCustom(false);
|
||||
this._line2d.setIsDestControlPointCustom(false);
|
||||
this._line2d.setCursor('pointer');
|
||||
this._line2d.setStroke(1, 'solid', strokeColor);
|
||||
this._line2d.setDashed(4, 2);
|
||||
this._focusShape = this._createLine(this.getLineType(), mindplot.ConnectionLine.SIMPLE_CURVED);
|
||||
this._focusShape.setStroke(2, "solid", "#3f96ff");
|
||||
|
||||
var ctrlPoints = this._line2d.getControlPoints();
|
||||
this._focusShape.setSrcControlPoint(ctrlPoints[0]);
|
||||
this._focusShape.setDestControlPoint(ctrlPoints[1]);
|
||||
this._focusShape.setVisibility(false);
|
||||
this._onFocus = false;
|
||||
this._isInWorkspace = false;
|
||||
this._controlPointsController = new mindplot.ControlPoint();
|
||||
|
||||
this._startArrow = new web2d.Arrow();
|
||||
this._startArrow.setStrokeColor(strokeColor);
|
||||
this._startArrow.setStrokeWidth(2);
|
||||
this.setShowStartArrow(true);
|
||||
|
||||
// Share style is disable ...
|
||||
if (this._showEndArrow) {
|
||||
this._endArrow = new web2d.Arrow();
|
||||
this._endArrow.setStrokeColor(strokeColor);
|
||||
this._endArrow.setStrokeWidth(2);
|
||||
}
|
||||
|
||||
// Position the line ...
|
||||
if ($defined(model.getSrcCtrlPoint())) {
|
||||
var srcPoint = model.getSrcCtrlPoint().clone();
|
||||
this.setSrcControlPoint(srcPoint);
|
||||
}
|
||||
if ($defined(model.getDestCtrlPoint())) {
|
||||
var destPoint = model.getDestCtrlPoint().clone();
|
||||
this.setDestControlPoint(destPoint);
|
||||
}
|
||||
},
|
||||
|
||||
setStroke: function (color, style, opacity) {
|
||||
this.parent(color, style, opacity);
|
||||
this._startArrow.setStrokeColor(color);
|
||||
},
|
||||
|
||||
redraw: function () {
|
||||
var line2d = this._line2d;
|
||||
var sourceTopic = this._sourceTopic;
|
||||
var sourcePosition = sourceTopic.getPosition();
|
||||
|
||||
var targetTopic = this._targetTopic;
|
||||
var targetPosition = targetTopic.getPosition();
|
||||
if (targetTopic.getType() == mindplot.model.INodeModel.CENTRAL_TOPIC_TYPE) {
|
||||
targetPosition = mindplot.util.Shape.workoutIncomingConnectionPoint(targetTopic, sourcePosition);
|
||||
}
|
||||
|
||||
var sPos, tPos;
|
||||
this._line2d.setStroke(2);
|
||||
var ctrlPoints = this._line2d.getControlPoints();
|
||||
if (!this._line2d.isDestControlPointCustom() && !this._line2d.isSrcControlPointCustom()) {
|
||||
|
||||
var defaultPoints = mindplot.util.Shape.calculateDefaultControlPoints(sourcePosition, targetPosition);
|
||||
ctrlPoints[0].x = defaultPoints[0].x;
|
||||
ctrlPoints[0].y = defaultPoints[0].y;
|
||||
|
||||
ctrlPoints[1].x = defaultPoints[1].x;
|
||||
ctrlPoints[1].y = defaultPoints[1].y;
|
||||
}
|
||||
var spoint = new core.Point();
|
||||
spoint.x = parseInt(ctrlPoints[0].x) + parseInt(sourcePosition.x);
|
||||
spoint.y = parseInt(ctrlPoints[0].y) + parseInt(sourcePosition.y);
|
||||
|
||||
var tpoint = new core.Point();
|
||||
tpoint.x = parseInt(ctrlPoints[1].x) + parseInt(targetPosition.x);
|
||||
tpoint.y = parseInt(ctrlPoints[1].y) + parseInt(targetPosition.y);
|
||||
|
||||
sPos = mindplot.util.Shape.calculateRelationShipPointCoordinates(sourceTopic, spoint);
|
||||
tPos = mindplot.util.Shape.calculateRelationShipPointCoordinates(targetTopic, tpoint);
|
||||
|
||||
line2d.setFrom(sPos.x, sPos.y);
|
||||
line2d.setTo(tPos.x, tPos.y);
|
||||
|
||||
line2d.moveToFront();
|
||||
|
||||
//Positionate Arrows
|
||||
this._positionArrows();
|
||||
|
||||
// Add connector ...
|
||||
this._positionateConnector(targetTopic);
|
||||
|
||||
if (this.isOnFocus()) {
|
||||
this._refreshShape();
|
||||
}
|
||||
this._focusShape.moveToBack();
|
||||
this._controlPointsController.redraw();
|
||||
},
|
||||
|
||||
_positionArrows: function () {
|
||||
var tpos = this._line2d.getTo();
|
||||
var spos = this._line2d.getFrom();
|
||||
|
||||
this._startArrow.setFrom(spos.x, spos.y);
|
||||
this._startArrow.moveToBack();
|
||||
|
||||
if (this._endArrow) {
|
||||
this._endArrow.setFrom(tpos.x, tpos.y);
|
||||
this._endArrow.moveToBack();
|
||||
}
|
||||
|
||||
if (this._line2d.getType() == "CurvedLine") {
|
||||
var controlPoints = this._line2d.getControlPoints();
|
||||
this._startArrow.setControlPoint(controlPoints[0]);
|
||||
if (this._endArrow) {
|
||||
this._endArrow.setControlPoint(controlPoints[1]);
|
||||
}
|
||||
} else {
|
||||
this._startArrow.setControlPoint(this._line2d.getTo());
|
||||
if (this._endArrow) {
|
||||
this._endArrow.setControlPoint(this._line2d.getFrom());
|
||||
}
|
||||
}
|
||||
|
||||
if (this._showEndArrow) {
|
||||
this._endArrow.setVisibility(this.isVisible());
|
||||
}
|
||||
this._startArrow.setVisibility(this.isVisible() && this._showStartArrow);
|
||||
},
|
||||
|
||||
addToWorkspace: function (workspace) {
|
||||
workspace.append(this._focusShape);
|
||||
workspace.append(this._controlPointsController);
|
||||
|
||||
this._controlPointControllerListener = this._initializeControlPointController.bind(this);
|
||||
this._line2d.addEvent('click', this._controlPointControllerListener);
|
||||
this._isInWorkspace = true;
|
||||
|
||||
workspace.append(this._startArrow);
|
||||
if (this._endArrow)
|
||||
workspace.append(this._endArrow);
|
||||
|
||||
this.parent(workspace);
|
||||
this._positionArrows();
|
||||
this.redraw();
|
||||
|
||||
},
|
||||
|
||||
_initializeControlPointController: function () {
|
||||
this.setOnFocus(true);
|
||||
},
|
||||
|
||||
removeFromWorkspace: function (workspace) {
|
||||
workspace.removeChild(this._focusShape);
|
||||
workspace.removeChild(this._controlPointsController);
|
||||
this._line2d.removeEvent('click', this._controlPointControllerListener);
|
||||
this._isInWorkspace = false;
|
||||
workspace.removeChild(this._startArrow);
|
||||
if (this._endArrow)
|
||||
workspace.removeChild(this._endArrow);
|
||||
|
||||
this.parent(workspace);
|
||||
},
|
||||
|
||||
getType: function () {
|
||||
return mindplot.Relationship.type;
|
||||
},
|
||||
|
||||
setOnFocus: function (focus) {
|
||||
// Change focus shape
|
||||
if (this.isOnFocus() != focus) {
|
||||
if (focus) {
|
||||
this._refreshShape();
|
||||
this._controlPointsController.setLine(this);
|
||||
}
|
||||
this._focusShape.setVisibility(focus);
|
||||
|
||||
this._controlPointsController.setVisibility(focus);
|
||||
this._onFocus = focus;
|
||||
this.fireEvent(focus ? 'ontfocus' : 'ontblur', this);
|
||||
}
|
||||
},
|
||||
|
||||
_refreshShape: function () {
|
||||
var sPos = this._line2d.getFrom();
|
||||
var tPos = this._line2d.getTo();
|
||||
var ctrlPoints = this._line2d.getControlPoints();
|
||||
this._focusShape.setFrom(sPos.x, sPos.y);
|
||||
this._focusShape.setTo(tPos.x, tPos.y);
|
||||
var shapeCtrlPoints = this._focusShape.getControlPoints();
|
||||
shapeCtrlPoints[0].x = ctrlPoints[0].x;
|
||||
shapeCtrlPoints[0].y = ctrlPoints[0].y;
|
||||
shapeCtrlPoints[1].x = ctrlPoints[1].x;
|
||||
shapeCtrlPoints[1].y = ctrlPoints[1].y;
|
||||
this._focusShape.updateLine();
|
||||
},
|
||||
|
||||
addEvent: function (type, listener) {
|
||||
// Translate to web 2d events ...
|
||||
if (type == 'onfocus') {
|
||||
type = 'mousedown';
|
||||
}
|
||||
|
||||
var line = this._line2d;
|
||||
line.addEvent(type, listener);
|
||||
},
|
||||
|
||||
isOnFocus: function () {
|
||||
return this._onFocus;
|
||||
},
|
||||
|
||||
isInWorkspace: function () {
|
||||
return this._isInWorkspace;
|
||||
},
|
||||
|
||||
setVisibility: function (value) {
|
||||
this.parent(value);
|
||||
if (this._showEndArrow)
|
||||
this._endArrow.setVisibility(this._showEndArrow);
|
||||
this._startArrow.setVisibility(this._showStartArrow && value);
|
||||
},
|
||||
|
||||
setOpacity: function (opacity) {
|
||||
this.parent(opacity);
|
||||
if (this._showEndArrow)
|
||||
this._endArrow.setOpacity(opacity);
|
||||
if (this._showStartArrow)
|
||||
this._startArrow.setOpacity(opacity);
|
||||
},
|
||||
|
||||
setShowEndArrow: function (visible) {
|
||||
this._showEndArrow = visible;
|
||||
if (this._isInWorkspace)
|
||||
this.redraw();
|
||||
},
|
||||
|
||||
setShowStartArrow: function (visible) {
|
||||
this._showStartArrow = visible;
|
||||
if (this._isInWorkspace)
|
||||
this.redraw();
|
||||
},
|
||||
|
||||
setFrom: function (x, y) {
|
||||
$assert($defined(x), "x must be defined");
|
||||
$assert($defined(y), "y must be defined");
|
||||
|
||||
this._line2d.setFrom(x, y);
|
||||
this._startArrow.setFrom(x, y);
|
||||
},
|
||||
|
||||
setTo: function (x, y) {
|
||||
$assert($defined(x), "x must be defined");
|
||||
$assert($defined(y), "y must be defined");
|
||||
|
||||
this._line2d.setTo(x, y);
|
||||
if (this._endArrow)
|
||||
this._endArrow.setFrom(x, y);
|
||||
},
|
||||
|
||||
setSrcControlPoint: function (control) {
|
||||
this._line2d.setSrcControlPoint(control);
|
||||
this._startArrow.setControlPoint(control);
|
||||
},
|
||||
|
||||
setDestControlPoint: function (control) {
|
||||
this._line2d.setDestControlPoint(control);
|
||||
if (this._showEndArrow)
|
||||
this._endArrow.setControlPoint(control);
|
||||
},
|
||||
|
||||
getControlPoints: function () {
|
||||
return this._line2d.getControlPoints();
|
||||
},
|
||||
|
||||
isSrcControlPointCustom: function () {
|
||||
return this._line2d.isSrcControlPointCustom();
|
||||
},
|
||||
|
||||
isDestControlPointCustom: function () {
|
||||
return this._line2d.isDestControlPointCustom();
|
||||
},
|
||||
|
||||
setIsSrcControlPointCustom: function (isCustom) {
|
||||
this._line2d.setIsSrcControlPointCustom(isCustom);
|
||||
},
|
||||
|
||||
setIsDestControlPointCustom: function (isCustom) {
|
||||
this._line2d.setIsDestControlPointCustom(isCustom);
|
||||
},
|
||||
|
||||
getId: function () {
|
||||
return this._model.getId();
|
||||
},
|
||||
|
||||
fireEvent: function (type, event) {
|
||||
var elem = this._line2d;
|
||||
elem.trigger(type, event);
|
||||
}
|
||||
});
|
@ -1,160 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.RelationshipPivot = new Class({
|
||||
initialize: function (workspace, designer) {
|
||||
$assert(workspace, "workspace can not be null");
|
||||
$assert(designer, "designer can not be null");
|
||||
this._workspace = workspace;
|
||||
this._designer = designer;
|
||||
|
||||
//FIXME: the aim of the migration is remove .bind mootools method, please remove these!
|
||||
this._mouseMoveEvent = this._mouseMove.bind(this);
|
||||
this._onClickEvent = this._cleanOnMouseClick.bind(this);
|
||||
this._onTopicClick = this._connectOnFocus.bind(this);
|
||||
|
||||
},
|
||||
|
||||
start: function (sourceTopic, targetPos) {
|
||||
$assert(sourceTopic, "sourceTopic can not be null");
|
||||
$assert(targetPos, "targetPos can not be null");
|
||||
|
||||
this.dispose();
|
||||
this._sourceTopic = sourceTopic;
|
||||
if (sourceTopic != null) {
|
||||
this._workspace.enableWorkspaceEvents(false);
|
||||
|
||||
var sourcePos = sourceTopic.getPosition();
|
||||
var strokeColor = mindplot.Relationship.getStrokeColor();
|
||||
|
||||
this._pivot = new web2d.CurvedLine();
|
||||
this._pivot.setStyle(web2d.CurvedLine.SIMPLE_LINE);
|
||||
|
||||
var fromPos = this._calculateFromPosition(sourcePos);
|
||||
this._pivot.setFrom(fromPos.x, fromPos.y);
|
||||
|
||||
this._pivot.setTo(targetPos.x, targetPos.y);
|
||||
this._pivot.setStroke(2, 'solid', strokeColor);
|
||||
this._pivot.setDashed(4, 2);
|
||||
|
||||
this._startArrow = new web2d.Arrow();
|
||||
this._startArrow.setStrokeColor(strokeColor);
|
||||
this._startArrow.setStrokeWidth(2);
|
||||
this._startArrow.setFrom(sourcePos.x, sourcePos.y);
|
||||
|
||||
this._workspace.append(this._pivot);
|
||||
this._workspace.append(this._startArrow);
|
||||
|
||||
this._workspace.addEvent('mousemove', this._mouseMoveEvent);
|
||||
this._workspace.addEvent('click', this._onClickEvent);
|
||||
|
||||
// Register focus events on all topics ...
|
||||
var model = this._designer.getModel();
|
||||
var topics = model.getTopics();
|
||||
_.each(topics, function (topic) {
|
||||
topic.addEvent('ontfocus', this._onTopicClick);
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
dispose: function () {
|
||||
var workspace = this._workspace;
|
||||
|
||||
if (this._isActive()) {
|
||||
workspace.removeEvent('mousemove', this._mouseMoveEvent);
|
||||
workspace.removeEvent('click', this._onClickEvent);
|
||||
|
||||
var model = this._designer.getModel();
|
||||
var topics = model.getTopics();
|
||||
var me = this;
|
||||
_.each(topics, function (topic) {
|
||||
topic.removeEvent('ontfocus', me._onTopicClick);
|
||||
});
|
||||
|
||||
workspace.removeChild(this._pivot);
|
||||
workspace.removeChild(this._startArrow);
|
||||
workspace.enableWorkspaceEvents(true);
|
||||
|
||||
this._sourceTopic = null;
|
||||
this._pivot = null;
|
||||
this._startArrow = null;
|
||||
}
|
||||
},
|
||||
|
||||
_mouseMove: function (event) {
|
||||
var screen = this._workspace.getScreenManager();
|
||||
var pos = screen.getWorkspaceMousePosition(event);
|
||||
|
||||
// Leave the arrow a couple of pixels away from the cursor.
|
||||
var sourcePosition = this._sourceTopic.getPosition();
|
||||
var gapDistance = Math.sign(pos.x - sourcePosition.x) * 5;
|
||||
|
||||
var sPos = this._calculateFromPosition(pos);
|
||||
this._pivot.setFrom(sPos.x, sPos.y);
|
||||
|
||||
// Update target position ...
|
||||
this._pivot.setTo(pos.x - gapDistance, pos.y);
|
||||
|
||||
var controlPoints = this._pivot.getControlPoints();
|
||||
this._startArrow.setFrom(pos.x - gapDistance, pos.y);
|
||||
this._startArrow.setControlPoint(controlPoints[1]);
|
||||
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
},
|
||||
|
||||
_cleanOnMouseClick: function (event) {
|
||||
|
||||
// The user clicks on a desktop on in other element that is not a node.
|
||||
this.dispose();
|
||||
event.stopPropagation();
|
||||
},
|
||||
|
||||
_calculateFromPosition: function (toPosition) {
|
||||
|
||||
// Calculate origin position ...
|
||||
var sourcePosition = this._sourceTopic.getPosition();
|
||||
if (this._sourceTopic.getType() == mindplot.model.INodeModel.CENTRAL_TOPIC_TYPE) {
|
||||
sourcePosition = mindplot.util.Shape.workoutIncomingConnectionPoint(this._sourceTopic, toPosition);
|
||||
}
|
||||
var controlPoint = mindplot.util.Shape.calculateDefaultControlPoints(sourcePosition, toPosition);
|
||||
|
||||
var spoint = new core.Point();
|
||||
spoint.x = parseInt(controlPoint[0].x) + parseInt(sourcePosition.x);
|
||||
spoint.y = parseInt(controlPoint[0].y) + parseInt(sourcePosition.y);
|
||||
return mindplot.util.Shape.calculateRelationShipPointCoordinates(this._sourceTopic, spoint);
|
||||
},
|
||||
|
||||
_connectOnFocus: function (event, targetTopic) {
|
||||
var sourceTopic = this._sourceTopic;
|
||||
var mindmap = this._designer.getMindmap();
|
||||
|
||||
// Avoid circular connections ...
|
||||
if (targetTopic.getId() != sourceTopic.getId()) {
|
||||
var relModel = mindmap.createRelationship(targetTopic.getId(), sourceTopic.getId());
|
||||
this._designer._actionDispatcher.addRelationship(relModel);
|
||||
}
|
||||
this.dispose();
|
||||
},
|
||||
|
||||
_isActive: function () {
|
||||
return this._pivot != null;
|
||||
}
|
||||
});
|
||||
|
@ -1,163 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.RESTPersistenceManager = new Class({
|
||||
Extends: mindplot.PersistenceManager,
|
||||
initialize: function (options) {
|
||||
this.parent();
|
||||
$assert(options.documentUrl, "documentUrl can not be null");
|
||||
$assert(options.revertUrl, "revertUrl can not be null");
|
||||
$assert(options.lockUrl, "lockUrl can not be null");
|
||||
$assert(options.session, "session can not be null");
|
||||
$assert(options.timestamp, "timestamp can not be null");
|
||||
|
||||
this.documentUrl = options.documentUrl;
|
||||
this.revertUrl = options.revertUrl;
|
||||
this.lockUrl = options.lockUrl;
|
||||
this.timestamp = options.timestamp;
|
||||
this.session = options.session;
|
||||
},
|
||||
|
||||
saveMapXml: function (mapId, mapXml, pref, saveHistory, events, sync) {
|
||||
|
||||
var data = {
|
||||
id: mapId,
|
||||
xml: mapXml,
|
||||
properties: pref
|
||||
};
|
||||
|
||||
var persistence = this;
|
||||
var query = "minor=" + !saveHistory;
|
||||
query = query + "×tamp=" + this.timestamp;
|
||||
query = query + "&session=" + this.session;
|
||||
|
||||
if (!persistence.onSave) {
|
||||
|
||||
// Mark save in process and fire a event unlocking the save ...
|
||||
persistence.onSave = true;
|
||||
persistence.clearTimeout = setTimeout(function () {
|
||||
persistence.clearTimeout = null;
|
||||
persistence.onSave = false;
|
||||
}, 10000);
|
||||
|
||||
$.ajax({
|
||||
url: this.documentUrl.replace("{id}", mapId) + "?" + query,
|
||||
type: 'put',
|
||||
dataType: "json",
|
||||
data: JSON.stringify(data),
|
||||
contentType: "application/json; charset=utf-8",
|
||||
async: !sync,
|
||||
|
||||
success: function (data, textStatus, jqXHRresponseText) {
|
||||
persistence.timestamp = data;
|
||||
events.onSuccess();
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
events.onError(persistence._buildError());
|
||||
},
|
||||
complete: function () {
|
||||
// Clear event timeout ...
|
||||
if (persistence.clearTimeout) {
|
||||
clearTimeout(persistence.clearTimeout);
|
||||
}
|
||||
persistence.onSave = false;
|
||||
},
|
||||
fail: function (xhr, textStatus) {
|
||||
|
||||
var responseText = xhr.responseText;
|
||||
var userMsg = {severity: "SEVERE", message: $msg('SAVE_COULD_NOT_BE_COMPLETED')};
|
||||
|
||||
var contentType = xhr.getResponseHeader("Content-Type");
|
||||
if (contentType != null && contentType.indexOf("application/json") != -1) {
|
||||
var serverMsg = null;
|
||||
try {
|
||||
serverMsg = $.parseJSON(responseText);
|
||||
serverMsg = serverMsg.globalSeverity ? serverMsg : null;
|
||||
} catch (e) {
|
||||
// Message could not be decoded ...
|
||||
}
|
||||
userMsg = persistence._buildError(serverMsg);
|
||||
|
||||
} else {
|
||||
if (this.status == 405) {
|
||||
userMsg = {severity: "SEVERE", message: $msg('SESSION_EXPIRED')};
|
||||
}
|
||||
}
|
||||
events.onError(userMsg);
|
||||
persistence.onSave = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
discardChanges: function (mapId) {
|
||||
$.ajax({
|
||||
url: this.revertUrl.replace("{id}", mapId),
|
||||
async: false,
|
||||
method: 'post',
|
||||
headers: {"Content-Type": "application/json; charset=utf-8", "Accept": "application/json"}
|
||||
});
|
||||
},
|
||||
|
||||
unlockMap: function (mindmap) {
|
||||
var mapId = mindmap.getId();
|
||||
$.ajax({
|
||||
url: this.lockUrl.replace("{id}", mapId),
|
||||
async: false,
|
||||
method: 'put',
|
||||
headers: {"Content-Type": "text/plain"},
|
||||
data: "false"
|
||||
});
|
||||
},
|
||||
|
||||
_buildError: function (jsonSeverResponse) {
|
||||
var message = jsonSeverResponse ? jsonSeverResponse.globalErrors[0] : null;
|
||||
var severity = jsonSeverResponse ? jsonSeverResponse.globalSeverity : null;
|
||||
|
||||
if (!message) {
|
||||
message = $msg('SAVE_COULD_NOT_BE_COMPLETED');
|
||||
}
|
||||
|
||||
if (!severity) {
|
||||
severity = "INFO";
|
||||
}
|
||||
return {severity: severity, message: message};
|
||||
},
|
||||
|
||||
loadMapDom: function (mapId) {
|
||||
// Let's try to open one from the local directory ...
|
||||
var xml;
|
||||
$.ajax({
|
||||
url: this.documentUrl.replace("{id}", mapId) + "/xml",
|
||||
method: 'get',
|
||||
async: false,
|
||||
headers: {"Content-Type": "text/plain", "Accept": "application/xml"},
|
||||
success: function (responseText) {
|
||||
xml = responseText;
|
||||
}
|
||||
});
|
||||
|
||||
// If I could not load it from a file, hard code one.
|
||||
if (xml == null) {
|
||||
throw new Error("Map could not be loaded");
|
||||
}
|
||||
|
||||
return xml;
|
||||
}
|
||||
}
|
||||
);
|
@ -1,149 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.ScreenManager = new Class({
|
||||
initialize: function (divElement) {
|
||||
$assert(divElement, "can not be null");
|
||||
this._divContainer = divElement;
|
||||
this._padding = {x: 0, y: 0};
|
||||
|
||||
// Ignore default click event propagation. Prevent 'click' event on drag.
|
||||
this._clickEvents = [];
|
||||
this._divContainer.bind('click', function (event) {
|
||||
event.stopPropagation()
|
||||
});
|
||||
|
||||
this._divContainer.bind('dblclick', function (event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
});
|
||||
},
|
||||
|
||||
setScale: function (scale) {
|
||||
$assert(scale, 'Screen scale can not be null');
|
||||
this._scale = scale;
|
||||
},
|
||||
|
||||
addEvent: function (event, listener) {
|
||||
if (event == 'click')
|
||||
this._clickEvents.push(listener);
|
||||
else
|
||||
this._divContainer.bind(event, listener);
|
||||
},
|
||||
|
||||
removeEvent: function (event, listener) {
|
||||
if (event == 'click') {
|
||||
this._clickEvents.remove(listener);
|
||||
}
|
||||
else {
|
||||
this._divContainer.unbind(event, listener);
|
||||
}
|
||||
},
|
||||
|
||||
fireEvent: function (type, event) {
|
||||
if (type == 'click') {
|
||||
_.each(this._clickEvents, function (listener) {
|
||||
listener(type, event);
|
||||
});
|
||||
}
|
||||
else {
|
||||
this._divContainer.trigger(type, event);
|
||||
}
|
||||
},
|
||||
|
||||
_getElementPosition: function (elem) {
|
||||
// Retrieve current element position.
|
||||
var elementPosition = elem.getPosition();
|
||||
var x = elementPosition.x;
|
||||
var y = elementPosition.y;
|
||||
|
||||
// Add workspace offset.
|
||||
x = x - this._padding.x;
|
||||
y = y - this._padding.y;
|
||||
|
||||
// Scale coordinate in order to be relative to the workspace. That's coord/size;
|
||||
x = x / this._scale;
|
||||
y = y / this._scale;
|
||||
|
||||
// Remove decimal part..
|
||||
return {x: x, y: y};
|
||||
},
|
||||
|
||||
getWorkspaceIconPosition: function (e) {
|
||||
// Retrieve current icon position.
|
||||
var image = e.getImage();
|
||||
var elementPosition = image.getPosition();
|
||||
var imageSize = e.getSize();
|
||||
|
||||
//Add group offset
|
||||
var iconGroup = e.getGroup();
|
||||
var group = iconGroup.getNativeElement();
|
||||
var coordOrigin = group.getCoordOrigin();
|
||||
var groupSize = group.getSize();
|
||||
var coordSize = group.getCoordSize();
|
||||
|
||||
var scale = {x: coordSize.width / parseInt(groupSize.width), y: coordSize.height / parseInt(groupSize.height)};
|
||||
|
||||
var x = (elementPosition.x - coordOrigin.x - (parseInt(imageSize.width) / 2)) / scale.x;
|
||||
var y = (elementPosition.y - coordOrigin.y - (parseInt(imageSize.height) / 2)) / scale.y;
|
||||
|
||||
//Retrieve iconGroup Position
|
||||
var groupPosition = iconGroup.getPosition();
|
||||
x = x + groupPosition.x;
|
||||
y = y + groupPosition.y;
|
||||
|
||||
//Retrieve topic Position
|
||||
var topic = iconGroup.getTopic();
|
||||
var topicPosition = this._getElementPosition(topic);
|
||||
topicPosition.x = topicPosition.x - (parseInt(topic.getSize().width) / 2);
|
||||
|
||||
// Remove decimal part..
|
||||
return {x: x + topicPosition.x, y: y + topicPosition.y};
|
||||
},
|
||||
|
||||
getWorkspaceMousePosition: function (event) {
|
||||
// Retrieve current mouse position.
|
||||
var x = event.clientX;
|
||||
var y = event.clientY;
|
||||
|
||||
//FIXME: paulo: why? Subtract div position.
|
||||
/*var containerPosition = this.getContainer().position();
|
||||
x = x - containerPosition.x;
|
||||
y = y - containerPosition.y;*/
|
||||
|
||||
// Scale coordinate in order to be relative to the workspace. That's coordSize/size;
|
||||
x = x * this._scale;
|
||||
y = y * this._scale;
|
||||
|
||||
// Add workspace offset.
|
||||
x = x + this._padding.x;
|
||||
y = y + this._padding.y;
|
||||
|
||||
// Remove decimal part..
|
||||
return new core.Point(x, y);
|
||||
},
|
||||
|
||||
getContainer: function () {
|
||||
return this._divContainer;
|
||||
},
|
||||
|
||||
setOffset: function (x, y) {
|
||||
this._padding.x = x;
|
||||
this._padding.y = y;
|
||||
}
|
||||
});
|
@ -1,107 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.ShirinkConnector = new Class({
|
||||
initialize: function (topic) {
|
||||
|
||||
var ellipse = new web2d.Elipse(mindplot.Topic.prototype.INNER_RECT_ATTRIBUTES);
|
||||
this._ellipse = ellipse;
|
||||
ellipse.setFill('rgb(62,118,179)');
|
||||
|
||||
ellipse.setSize(mindplot.Topic.CONNECTOR_WIDTH, mindplot.Topic.CONNECTOR_WIDTH);
|
||||
ellipse.addEvent('click', function (event) {
|
||||
var model = topic.getModel();
|
||||
var collapse = !model.areChildrenShrunken();
|
||||
|
||||
var topicId = topic.getId();
|
||||
var actionDispatcher = mindplot.ActionDispatcher.getInstance();
|
||||
actionDispatcher.shrinkBranch([topicId], collapse);
|
||||
|
||||
event.stopPropagation();
|
||||
|
||||
});
|
||||
|
||||
ellipse.addEvent('mousedown', function (event) {
|
||||
// Avoid node creation ...
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
ellipse.addEvent('dblclick', function (event) {
|
||||
// Avoid node creation ...
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
ellipse.addEvent('mouseover', function (event) {
|
||||
|
||||
ellipse.setFill('rgb(153, 0, 255)');
|
||||
});
|
||||
var me = this;
|
||||
ellipse.addEvent('mouseout', function (event) {
|
||||
var color = topic.getBackgroundColor();
|
||||
me.setFill(color);
|
||||
});
|
||||
|
||||
ellipse.setCursor('default');
|
||||
this._fillColor = '#f7f7f7';
|
||||
var model = topic.getModel();
|
||||
this.changeRender(model.areChildrenShrunken());
|
||||
|
||||
},
|
||||
|
||||
changeRender: function (isShrink) {
|
||||
var elipse = this._ellipse;
|
||||
if (isShrink) {
|
||||
elipse.setStroke('2', 'solid');
|
||||
} else {
|
||||
elipse.setStroke('1', 'solid');
|
||||
}
|
||||
},
|
||||
|
||||
setVisibility: function (value) {
|
||||
this._ellipse.setVisibility(value);
|
||||
},
|
||||
|
||||
setOpacity: function (opacity) {
|
||||
this._ellipse.setOpacity(opacity);
|
||||
},
|
||||
|
||||
setFill: function (color) {
|
||||
this._fillColor = color;
|
||||
this._ellipse.setFill(color);
|
||||
},
|
||||
|
||||
setAttribute: function (name, value) {
|
||||
this._ellipse.setAttribute(name, value);
|
||||
},
|
||||
|
||||
addToWorkspace: function (group) {
|
||||
group.append(this._ellipse);
|
||||
},
|
||||
|
||||
setPosition: function (x, y) {
|
||||
this._ellipse.setPosition(x, y);
|
||||
},
|
||||
|
||||
moveToBack: function () {
|
||||
this._ellipse.moveToBack();
|
||||
},
|
||||
|
||||
moveToFront: function () {
|
||||
this._ellipse.moveToFront();
|
||||
}
|
||||
});
|
@ -1,360 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.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");
|
||||
|
||||
var commandFunc = function (topic, value) {
|
||||
var result = topic.getPosition();
|
||||
mindplot.EventBus.instance.fireEvent(mindplot.EventBus.events.NodeMoveEvent, {
|
||||
node: topic.getModel(),
|
||||
position: value
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
var command = new mindplot.commands.GenericFunctionCommand(commandFunc, topicId, position);
|
||||
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) {
|
||||
var result = topic.getFontStyle();
|
||||
var style = (result == "italic") ? "normal" : "italic";
|
||||
topic.setFontStyle(style, true);
|
||||
return result;
|
||||
};
|
||||
var command = new mindplot.commands.GenericFunctionCommand(commandFunc, topicsIds);
|
||||
this.execute(command);
|
||||
|
||||
},
|
||||
|
||||
/** */
|
||||
changeTextToTopic: function (topicsIds, text) {
|
||||
$assert($defined(topicsIds), "topicsIds can not be null");
|
||||
|
||||
var commandFunc = function (topic, value) {
|
||||
var result = topic.getText();
|
||||
topic.setText(value);
|
||||
return result;
|
||||
};
|
||||
commandFunc.commandType = "changeTextToTopic";
|
||||
|
||||
var command = new mindplot.commands.GenericFunctionCommand(commandFunc, topicsIds, text);
|
||||
this.execute(command);
|
||||
},
|
||||
|
||||
/** */
|
||||
changeFontFamilyToTopic: function (topicIds, fontFamily) {
|
||||
$assert(topicIds, "topicIds can not be null");
|
||||
$assert(fontFamily, "fontFamily can not be null");
|
||||
|
||||
|
||||
var commandFunc = function (topic, fontFamily) {
|
||||
var result = topic.getFontFamily();
|
||||
topic.setFontFamily(fontFamily, true);
|
||||
|
||||
topic._adjustShapes();
|
||||
return result;
|
||||
};
|
||||
|
||||
var command = new mindplot.commands.GenericFunctionCommand(commandFunc, topicIds, fontFamily);
|
||||
this.execute(command);
|
||||
},
|
||||
|
||||
/** */
|
||||
changeFontColorToTopic: function (topicsIds, color) {
|
||||
$assert(topicsIds, "topicIds can not be null");
|
||||
$assert(color, "color can not be null");
|
||||
|
||||
var commandFunc = function (topic, color) {
|
||||
var result = topic.getFontColor();
|
||||
topic.setFontColor(color, true);
|
||||
return result;
|
||||
};
|
||||
|
||||
var command = new mindplot.commands.GenericFunctionCommand(commandFunc, topicsIds, color);
|
||||
command.discardDuplicated = "fontColorCommandId";
|
||||
this.execute(command);
|
||||
},
|
||||
|
||||
/** */
|
||||
changeBackgroundColorToTopic: function (topicsIds, color) {
|
||||
$assert(topicsIds, "topicIds can not be null");
|
||||
$assert(color, "color can not be null");
|
||||
|
||||
var commandFunc = function (topic, color) {
|
||||
var result = topic.getBackgroundColor();
|
||||
topic.setBackgroundColor(color);
|
||||
return result;
|
||||
};
|
||||
|
||||
var command = new mindplot.commands.GenericFunctionCommand(commandFunc, topicsIds, color);
|
||||
command.discardDuplicated = "backColor";
|
||||
this.execute(command);
|
||||
},
|
||||
|
||||
/** */
|
||||
changeBorderColorToTopic: function (topicsIds, color) {
|
||||
$assert(topicsIds, "topicIds can not be null");
|
||||
$assert(color, "topicIds can not be null");
|
||||
|
||||
var commandFunc = function (topic, color) {
|
||||
var result = topic.getBorderColor();
|
||||
topic.setBorderColor(color);
|
||||
return result;
|
||||
};
|
||||
|
||||
var command = new mindplot.commands.GenericFunctionCommand(commandFunc, topicsIds, color);
|
||||
command.discardDuplicated = "borderColorCommandId";
|
||||
this.execute(command);
|
||||
},
|
||||
|
||||
/** */
|
||||
changeFontSizeToTopic: function (topicsIds, size) {
|
||||
$assert(topicsIds, "topicIds can not be null");
|
||||
$assert(size, "size can not be null");
|
||||
|
||||
var commandFunc = function (topic, size) {
|
||||
var result = topic.getFontSize();
|
||||
topic.setFontSize(size, true);
|
||||
|
||||
topic._adjustShapes();
|
||||
return result;
|
||||
};
|
||||
|
||||
var command = new mindplot.commands.GenericFunctionCommand(commandFunc, topicsIds, size);
|
||||
this.execute(command);
|
||||
},
|
||||
|
||||
/** */
|
||||
changeShapeTypeToTopic: function (topicsIds, shapeType) {
|
||||
$assert(topicsIds, "topicsIds can not be null");
|
||||
$assert(shapeType, "shapeType can not be null");
|
||||
|
||||
var commandFunc = function (topic, shapeType) {
|
||||
var result = topic.getShapeType();
|
||||
topic.setShapeType(shapeType, true);
|
||||
return result;
|
||||
};
|
||||
|
||||
var command = new mindplot.commands.GenericFunctionCommand(commandFunc, topicsIds, shapeType);
|
||||
this.execute(command);
|
||||
},
|
||||
|
||||
/** */
|
||||
changeFontWeightToTopic: function (topicsIds) {
|
||||
$assert(topicsIds, "topicsIds can not be null");
|
||||
|
||||
var commandFunc = function (topic) {
|
||||
var result = topic.getFontWeight();
|
||||
var weight = (result == "bold") ? "normal" : "bold";
|
||||
topic.setFontWeight(weight, true);
|
||||
|
||||
topic._adjustShapes();
|
||||
return result;
|
||||
};
|
||||
|
||||
var command = new mindplot.commands.GenericFunctionCommand(commandFunc, topicsIds);
|
||||
this.execute(command);
|
||||
},
|
||||
|
||||
/** */
|
||||
shrinkBranch: function (topicsIds, collapse) {
|
||||
$assert(topicsIds, "topicsIds can not be null");
|
||||
|
||||
var commandFunc = function (topic, isShrink) {
|
||||
topic.setChildrenShrunken(isShrink);
|
||||
return !isShrink;
|
||||
};
|
||||
|
||||
var command = new mindplot.commands.GenericFunctionCommand(commandFunc, topicsIds, collapse);
|
||||
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(/** @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)) {
|
||||
topicsIds = [topicsIds];
|
||||
}
|
||||
|
||||
var designerTopics = this._designer.getModel().getTopics();
|
||||
var result = designerTopics.filter(function (topic) {
|
||||
return topicsIds.contains(topic.getId());
|
||||
});
|
||||
|
||||
if (result.length != topicsIds.length) {
|
||||
var ids = designerTopics.map(function (topic) {
|
||||
return topic.getId();
|
||||
});
|
||||
$assert(result.length == topicsIds.length, "Could not find topic. Result:" + result + ", Filter Criteria:" + topicsIds + ", Current Topics: [" + ids + "]");
|
||||
}
|
||||
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)) {
|
||||
relIds = [relIds];
|
||||
}
|
||||
|
||||
var designerRel = this._designer.getModel().getRelationships();
|
||||
return designerRel.filter(function (rel) {
|
||||
return relIds.contains(rel.getId());
|
||||
});
|
||||
},
|
||||
|
||||
/** */
|
||||
moveTopic: function (topic, position) {
|
||||
$assert(topic, "topic cannot be null");
|
||||
$assert(position, "position cannot be null");
|
||||
mindplot.EventBus.instance.fireEvent(mindplot.EventBus.events.NodeMoveEvent, {
|
||||
node: topic.getModel(),
|
||||
position: position
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1,268 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
//FIXME: Not used!
|
||||
mindplot.TextEditor = new Class({
|
||||
initialize: function (topic) {
|
||||
this._topic = topic;
|
||||
},
|
||||
|
||||
_buildEditor: function () {
|
||||
|
||||
this._size = {width: 500, height: 100};
|
||||
var result = new Element('div');
|
||||
result.setStyles({
|
||||
position: "absolute",
|
||||
display: "none",
|
||||
zIndex: "8",
|
||||
width: "500px",
|
||||
height: "100px"
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
var inputContainer = new Element('div');
|
||||
inputContainer.setStyles({
|
||||
border: "none",
|
||||
overflow: "auto"
|
||||
});
|
||||
inputContainer.inject(result);
|
||||
|
||||
var inputText = new Element('input',
|
||||
{
|
||||
type: "text",
|
||||
tabindex: '-1',
|
||||
value: ""
|
||||
}
|
||||
);
|
||||
inputText.setStyles({
|
||||
border: "none",
|
||||
background: "transparent"
|
||||
});
|
||||
inputText.inject(inputContainer);
|
||||
|
||||
var spanContainer = new Element('div');
|
||||
spanContainer.setStyle('visibility', "hidden");
|
||||
spanContainer.inject(result);
|
||||
|
||||
var spanElem = new Element('span', {tabindex: "-1"});
|
||||
spanElem.setStyle('white-space', "nowrap");
|
||||
spanElem.setStyle('nowrap', 'nowrap');
|
||||
spanElem.inject(spanContainer);
|
||||
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
_registerEvents: function (divElem) {
|
||||
var inputElem = this._getTextareaElem();
|
||||
var spanElem = this._getSpanElem();
|
||||
var me = this;
|
||||
|
||||
divElem.addEvent('keydown', function (event) {
|
||||
switch (event.key) {
|
||||
case 'esc':
|
||||
me.close(false);
|
||||
break;
|
||||
case 'enter':
|
||||
me.close(true);
|
||||
break;
|
||||
default:
|
||||
spanElem.innerHTML = inputElem.value;
|
||||
var size = inputElem.value.length + 1;
|
||||
inputElem.size = size;
|
||||
if (spanElem.offsetWidth > (parseInt(divElem.style.width) - 100)) {
|
||||
divElem.style.width = (spanElem.offsetWidth + 100) + "px";
|
||||
}
|
||||
break;
|
||||
}
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
// If the user clicks on the input, all event must be ignored ...
|
||||
divElem.addEvent('click', function (event) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
divElem.addEvent('dblclick', function (event) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
divElem.addEvent('mousedown', function (event) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
},
|
||||
|
||||
isVisible: function () {
|
||||
return $defined(this._containerElem) && this._containerElem.getStyle('display') == 'block';
|
||||
},
|
||||
|
||||
_updateModel: function () {
|
||||
|
||||
if (this._topic.getText() != this._getText()) {
|
||||
var text = this._getText();
|
||||
var topicId = this._topic.getId();
|
||||
|
||||
var actionDispatcher = mindplot.ActionDispatcher.getInstance();
|
||||
actionDispatcher.changeTextToTopic([topicId], text);
|
||||
}
|
||||
},
|
||||
|
||||
show: function (text) {
|
||||
|
||||
if (!this.isVisible()) {
|
||||
//Create editor ui
|
||||
var editorElem = this._buildEditor();
|
||||
editorElem.inject($(document.body)[0]);
|
||||
|
||||
this._containerElem = editorElem;
|
||||
this._registerEvents(editorElem);
|
||||
this._showEditor(text);
|
||||
}
|
||||
},
|
||||
|
||||
_showEditor: function (defaultText) {
|
||||
|
||||
var topic = this._topic;
|
||||
|
||||
// Hide topic text ...
|
||||
topic.getTextShape().setVisibility(false);
|
||||
|
||||
// Set Editor Style
|
||||
var nodeText = topic.getTextShape();
|
||||
var font = nodeText.getFont();
|
||||
font.size = nodeText.getHtmlFontSize();
|
||||
font.color = nodeText.getColor();
|
||||
this._setStyle(font);
|
||||
|
||||
// Set editor's initial text
|
||||
var text = $defined(defaultText) ? defaultText : topic.getText();
|
||||
this._setText(text);
|
||||
|
||||
var me = this;
|
||||
// Set editor's initial size
|
||||
var displayFunc = function () {
|
||||
// Position the editor and set the size...
|
||||
var textShape = me._topic.getTextShape();
|
||||
|
||||
me._containerElem.css('display', 'block');
|
||||
|
||||
me._containerElem.offset(textShape.getNativePosition());
|
||||
// Set size ...
|
||||
var elemSize = topic.getSize();
|
||||
me._setEditorSize(elemSize.width, elemSize.height);
|
||||
|
||||
var textareaElem = me._getTextareaElem();
|
||||
textareaElem.focus();
|
||||
me._positionCursor(textareaElem, !$defined(defaultText));
|
||||
|
||||
};
|
||||
|
||||
displayFunc.delay(10);
|
||||
},
|
||||
|
||||
_setStyle: function (fontStyle) {
|
||||
var inputField = this._getTextareaElem();
|
||||
var spanField = this._getSpanElem();
|
||||
if (!$defined(fontStyle.font)) {
|
||||
fontStyle.font = "Arial";
|
||||
}
|
||||
if (!$defined(fontStyle.style)) {
|
||||
fontStyle.style = "normal";
|
||||
}
|
||||
if (!$defined(fontStyle.weight)) {
|
||||
fontStyle.weight = "normal";
|
||||
}
|
||||
if (!$defined(fontStyle.size)) {
|
||||
fontStyle.size = 12;
|
||||
}
|
||||
inputField.style.fontSize = fontStyle.size + "px";
|
||||
inputField.style.fontFamily = fontStyle.font;
|
||||
inputField.style.fontStyle = fontStyle.style;
|
||||
inputField.style.fontWeight = fontStyle.weight;
|
||||
inputField.style.color = fontStyle.color;
|
||||
spanField.style.fontFamily = fontStyle.font;
|
||||
spanField.style.fontStyle = fontStyle.style;
|
||||
spanField.style.fontWeight = fontStyle.weight;
|
||||
spanField.style.fontSize = fontStyle.size + "px";
|
||||
},
|
||||
|
||||
_setText: function (text) {
|
||||
var inputField = this._getTextareaElem();
|
||||
inputField.size = text.length + 1;
|
||||
this._containerElem.style.width = (inputField.size * parseInt(inputField.style.fontSize) + 100) + "px";
|
||||
var spanField = this._getSpanElem();
|
||||
spanField.innerHTML = text;
|
||||
inputField.value = text;
|
||||
},
|
||||
|
||||
_getText: function () {
|
||||
return this._getTextareaElem().value;
|
||||
},
|
||||
|
||||
_getTextareaElem: function () {
|
||||
return this._containerElem.getElement('input');
|
||||
},
|
||||
|
||||
_getSpanElem: function () {
|
||||
return this._containerElem.getElement('span');
|
||||
},
|
||||
|
||||
_setEditorSize: function (width, height) {
|
||||
var textShape = this._topic.getTextShape();
|
||||
var scale = web2d.peer.utils.TransformUtil.workoutScale(textShape._peer);
|
||||
this._size = {width: width * scale.width, height: height * scale.height};
|
||||
this._containerElem.style.width = this._size.width * 2 + "px";
|
||||
this._containerElem.style.height = this._size.height + "px";
|
||||
},
|
||||
|
||||
_positionCursor: function (inputElem, selectText) {
|
||||
// Select text if it's required ...
|
||||
if (inputElem.createTextRange) //ie
|
||||
{
|
||||
var range = inputElem.createTextRange();
|
||||
var pos = inputElem.value.length;
|
||||
if (!selectText) {
|
||||
range.select();
|
||||
range.move("character", pos);
|
||||
}
|
||||
else {
|
||||
range.move("character", pos);
|
||||
range.select();
|
||||
}
|
||||
}
|
||||
else if (!selectText) {
|
||||
inputElem.setSelectionRange(0, inputElem.value.length);
|
||||
}
|
||||
},
|
||||
|
||||
close: function (update) {
|
||||
if (this.isVisible()) {
|
||||
// Update changes ...
|
||||
if (!$defined(update) || update) {
|
||||
this._updateModel();
|
||||
}
|
||||
|
||||
// Let make the visible text in the node visible again ...
|
||||
this._topic.getTextShape().setVisibility(true);
|
||||
|
||||
// Remove it form the screen ...
|
||||
this._containerElem.dispose();
|
||||
this._containerElem = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
mindplot.TextEditorFactory = {};
|
||||
|
||||
mindplot.TextEditorFactory.getTextEditorFromName = function (name) {
|
||||
var editorClass = null;
|
||||
if (name == "RichTextEditor") {
|
||||
editorClass = mindplot.RichTextEditor;
|
||||
} else {
|
||||
editorClass = mindplot.TextEditor;
|
||||
}
|
||||
return editorClass;
|
||||
};
|
File diff suppressed because it is too large
Load Diff
@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.TopicEventDispatcher = new Class({
|
||||
Extends: mindplot.Events,
|
||||
Static: {
|
||||
_instance: null,
|
||||
|
||||
configure: function (readOnly) {
|
||||
this._instance = new mindplot.TopicEventDispatcher(readOnly);
|
||||
},
|
||||
|
||||
getInstance: function () {
|
||||
return this._instance;
|
||||
}
|
||||
},
|
||||
|
||||
initialize: function (readOnly) {
|
||||
this._readOnly = readOnly;
|
||||
this._activeEditor = null;
|
||||
this._multilineEditor = new mindplot.MultilineTextEditor();
|
||||
},
|
||||
|
||||
close: function (update) {
|
||||
if (this.isVisible()) {
|
||||
this._activeEditor.close(update);
|
||||
this._activeEditor = null;
|
||||
}
|
||||
},
|
||||
|
||||
show: function (topic, options) {
|
||||
this.process(mindplot.TopicEvent.EDIT, topic, options);
|
||||
},
|
||||
|
||||
process: function (eventType, topic, options) {
|
||||
$assert(eventType, "eventType can not be null");
|
||||
|
||||
// Close all previous open editor ....
|
||||
if (this.isVisible()) {
|
||||
this.close();
|
||||
}
|
||||
|
||||
// Open the new editor ...
|
||||
var model = topic.getModel();
|
||||
if (model.getShapeType() != mindplot.model.TopicShape.IMAGE && !this._readOnly && eventType == mindplot.TopicEvent.EDIT) {
|
||||
this._multilineEditor.show(topic, options ? options.text : null);
|
||||
this._activeEditor = this._multilineEditor;
|
||||
} else {
|
||||
this.fireEvent(eventType, {model: model, readOnly: this._readOnly});
|
||||
}
|
||||
},
|
||||
|
||||
isVisible: function () {
|
||||
return this._activeEditor != null && this._activeEditor.isVisible();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
mindplot.TopicEvent = {
|
||||
EDIT: "editnode",
|
||||
CLICK: "clicknode"
|
||||
};
|
||||
|
@ -1,91 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** */
|
||||
mindplot.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');
|
||||
|
||||
var model = mindplot.TopicFeature._featuresMetadataById.filter(function (elem) {
|
||||
return elem.id == type;
|
||||
})[0].model;
|
||||
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');
|
||||
|
||||
var icon = mindplot.TopicFeature._featuresMetadataById.filter(function (elem) {
|
||||
return elem.id == model.getType();
|
||||
})[0].icon;
|
||||
return new icon(topic, model, readOnly);
|
||||
}
|
||||
};
|
||||
|
||||
mindplot.TopicFeature._featuresMetadataById = [mindplot.TopicFeature.Icon, mindplot.TopicFeature.Link, mindplot.TopicFeature.Note];
|
||||
|
||||
|
@ -1,132 +0,0 @@
|
||||
/*
|
||||
* Copyright [2011] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
mindplot.TopicStyle = new Class({
|
||||
Static: {
|
||||
_getStyles: function (topic) {
|
||||
$assert(topic, "topic can not be null");
|
||||
|
||||
var result;
|
||||
if (topic.isCentralTopic()) {
|
||||
result = mindplot.TopicStyle.STYLES.CENTRAL_TOPIC;
|
||||
} else {
|
||||
var targetTopic = topic.getOutgoingConnectedTopic();
|
||||
if ($defined(targetTopic)) {
|
||||
if (targetTopic.isCentralTopic()) {
|
||||
result = mindplot.TopicStyle.STYLES.MAIN_TOPIC;
|
||||
} else {
|
||||
result = mindplot.TopicStyle.STYLES.SUB_TOPIC;
|
||||
}
|
||||
} else {
|
||||
result = mindplot.TopicStyle.STYLES.ISOLATED_TOPIC;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
defaultText: function (topic) {
|
||||
var msgKey = this._getStyles(topic).msgKey;
|
||||
return $msg(msgKey);
|
||||
},
|
||||
|
||||
defaultFontStyle: function (topic) {
|
||||
return this._getStyles(topic).fontStyle;
|
||||
},
|
||||
|
||||
defaultBackgroundColor: function (topic) {
|
||||
return this._getStyles(topic).backgroundColor;
|
||||
},
|
||||
|
||||
defaultBorderColor: function (topic) {
|
||||
return this._getStyles(topic).borderColor;
|
||||
},
|
||||
|
||||
getInnerPadding: function (topic) {
|
||||
return this._getStyles(topic).innerPadding;
|
||||
},
|
||||
|
||||
defaultShapeType: function (topic) {
|
||||
return this._getStyles(topic).shapeType;
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
mindplot.TopicStyle.STYLES =
|
||||
{
|
||||
CENTRAL_TOPIC: {
|
||||
borderColor: 'rgb(57,113,177)',
|
||||
backgroundColor: 'rgb(80,157,192)',
|
||||
fontStyle: {
|
||||
font: "Verdana",
|
||||
size: 10,
|
||||
style: "normal",
|
||||
weight: "bold",
|
||||
color: "#ffffff"
|
||||
},
|
||||
msgKey: 'CENTRAL_TOPIC',
|
||||
innerPadding: 11,
|
||||
shapeType: mindplot.model.TopicShape.ROUNDED_RECT
|
||||
},
|
||||
|
||||
MAIN_TOPIC: {
|
||||
borderColor: 'rgb(2,59,185)',
|
||||
backgroundColor: 'rgb(224,229,239)',
|
||||
fontStyle: {
|
||||
font: "Arial",
|
||||
size: 8,
|
||||
style: "normal",
|
||||
weight: "normal",
|
||||
color: "rgb(82,92,97)"
|
||||
},
|
||||
msgKey: 'MAIN_TOPIC',
|
||||
innerPadding: 3,
|
||||
shapeType: mindplot.model.TopicShape.LINE
|
||||
|
||||
},
|
||||
|
||||
SUB_TOPIC: {
|
||||
borderColor: 'rgb(2,59,185)',
|
||||
backgroundColor: 'rgb(224,229,239)',
|
||||
fontStyle: {
|
||||
font: "Arial",
|
||||
size: 6,
|
||||
style: "normal",
|
||||
weight: "normal",
|
||||
color: "rgb(82,92,97)"
|
||||
},
|
||||
msgKey: 'SUB_TOPIC',
|
||||
innerPadding: 3,
|
||||
shapeType: mindplot.model.TopicShape.LINE
|
||||
},
|
||||
|
||||
ISOLATED_TOPIC: {
|
||||
borderColor: 'rgb(2,59,185)',
|
||||
backgroundColor: 'rgb(224,229,239)',
|
||||
fontStyle: {
|
||||
font: "Verdana",
|
||||
size: 8,
|
||||
style: "normal",
|
||||
weight: "normal",
|
||||
color: "rgb(82,92,97)"
|
||||
},
|
||||
msgKey: 'ISOLATED_TOPIC',
|
||||
innerPadding: 4,
|
||||
shapeType: mindplot.model.TopicShape.LINE
|
||||
}
|
||||
};
|
||||
|
@ -1,227 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.Workspace = new Class({
|
||||
initialize: function (screenManager, zoom) {
|
||||
// Create a suitable container ...
|
||||
$assert(screenManager, 'Div container can not be null');
|
||||
$assert(zoom, 'zoom container can not be null');
|
||||
|
||||
this._zoom = zoom;
|
||||
this._screenManager = screenManager;
|
||||
|
||||
var divContainer = screenManager.getContainer();
|
||||
this._screenWidth = parseInt(divContainer.css('width'));
|
||||
this._screenHeight = parseInt(divContainer.css('height'));
|
||||
|
||||
// Initialize web2d workspace.
|
||||
var workspace = this._createWorkspace();
|
||||
this._workspace = workspace;
|
||||
|
||||
// Append to the workspace...
|
||||
workspace.addItAsChildTo(divContainer);
|
||||
this.setZoom(zoom, true);
|
||||
|
||||
// Register drag events ...
|
||||
this._registerDragEvents();
|
||||
this._eventsEnabled = true;
|
||||
},
|
||||
|
||||
_createWorkspace: function () {
|
||||
// Initialize workspace ...
|
||||
var coordOriginX = -(this._screenWidth / 2);
|
||||
var coordOriginY = -(this._screenHeight / 2);
|
||||
|
||||
var workspaceProfile = {
|
||||
width: this._screenWidth + "px",
|
||||
height: this._screenHeight + "px",
|
||||
coordSizeWidth: this._screenWidth,
|
||||
coordSizeHeight: this._screenHeight,
|
||||
coordOriginX: coordOriginX,
|
||||
coordOriginY: coordOriginY,
|
||||
fillColor: 'transparent',
|
||||
strokeWidth: 0
|
||||
};
|
||||
web2d.peer.Toolkit.init();
|
||||
return new web2d.Workspace(workspaceProfile);
|
||||
},
|
||||
|
||||
append: function (shape) {
|
||||
if ($defined(shape.addToWorkspace)) {
|
||||
shape.addToWorkspace(this);
|
||||
} else {
|
||||
this._workspace.append(shape);
|
||||
}
|
||||
},
|
||||
|
||||
removeChild: function (shape) {
|
||||
// Element is a node, not a web2d element?
|
||||
if ($defined(shape.removeFromWorkspace)) {
|
||||
shape.removeFromWorkspace(this);
|
||||
} else {
|
||||
this._workspace.removeChild(shape);
|
||||
}
|
||||
},
|
||||
|
||||
addEvent: function (type, listener) {
|
||||
this._workspace.addEvent(type, listener);
|
||||
},
|
||||
|
||||
removeEvent: function (type, listener) {
|
||||
$assert(type, 'type can not be null');
|
||||
$assert(listener, 'listener can not be null');
|
||||
this._workspace.removeEvent(type, listener);
|
||||
},
|
||||
|
||||
getSize: function () {
|
||||
return this._workspace.getCoordSize();
|
||||
},
|
||||
|
||||
setZoom: function (zoom, center) {
|
||||
this._zoom = zoom;
|
||||
var workspace = this._workspace;
|
||||
|
||||
// Update coord scale...
|
||||
var coordWidth = zoom * this._screenWidth;
|
||||
var coordHeight = zoom * this._screenHeight;
|
||||
workspace.setCoordSize(coordWidth, coordHeight);
|
||||
|
||||
// View port coords ...
|
||||
if (this._viewPort) {
|
||||
this._viewPort.width = this._viewPort.width * zoom;
|
||||
this._viewPort.height = this._viewPort.height * zoom;
|
||||
}
|
||||
|
||||
// Center topic....
|
||||
var coordOriginX;
|
||||
var coordOriginY;
|
||||
|
||||
if (center) {
|
||||
if (this._viewPort) {
|
||||
coordOriginX = -(this._viewPort.width / 2);
|
||||
coordOriginY = -(this._viewPort.height / 2);
|
||||
} else {
|
||||
coordOriginX = -(coordWidth / 2);
|
||||
coordOriginY = -(coordHeight / 2);
|
||||
}
|
||||
} else {
|
||||
var coordOrigin = workspace.getCoordOrigin();
|
||||
coordOriginX = coordOrigin.x;
|
||||
coordOriginY = coordOrigin.y;
|
||||
}
|
||||
|
||||
workspace.setCoordOrigin(coordOriginX, coordOriginY);
|
||||
|
||||
// Update screen.
|
||||
this._screenManager.setOffset(coordOriginX, coordOriginY);
|
||||
this._screenManager.setScale(zoom);
|
||||
|
||||
// Some changes in the screen. Let's fire an update event...
|
||||
this._screenManager.fireEvent('update');
|
||||
},
|
||||
|
||||
getScreenManager: function () {
|
||||
return this._screenManager;
|
||||
},
|
||||
|
||||
enableWorkspaceEvents: function (value) {
|
||||
this._eventsEnabled = value;
|
||||
},
|
||||
|
||||
isWorkspaceEventsEnabled: function () {
|
||||
return this._eventsEnabled;
|
||||
},
|
||||
|
||||
dumpNativeChart: function () {
|
||||
return this._workspace.dumpNativeChart();
|
||||
},
|
||||
|
||||
_registerDragEvents: function () {
|
||||
var workspace = this._workspace;
|
||||
var screenManager = this._screenManager;
|
||||
var mWorkspace = this;
|
||||
var mouseDownListener = function (event) {
|
||||
if (!$defined(workspace._mouseMoveListener)) {
|
||||
if (mWorkspace.isWorkspaceEventsEnabled()) {
|
||||
mWorkspace.enableWorkspaceEvents(false);
|
||||
|
||||
var mouseDownPosition = screenManager.getWorkspaceMousePosition(event);
|
||||
var originalCoordOrigin = workspace.getCoordOrigin();
|
||||
|
||||
var wasDragged = false;
|
||||
workspace._mouseMoveListener = function (event) {
|
||||
|
||||
var currentMousePosition = screenManager.getWorkspaceMousePosition(event);
|
||||
|
||||
var offsetX = currentMousePosition.x - mouseDownPosition.x;
|
||||
var coordOriginX = -offsetX + originalCoordOrigin.x;
|
||||
|
||||
var offsetY = currentMousePosition.y - mouseDownPosition.y;
|
||||
var coordOriginY = -offsetY + originalCoordOrigin.y;
|
||||
|
||||
workspace.setCoordOrigin(coordOriginX, coordOriginY);
|
||||
|
||||
// Change cursor.
|
||||
if (Browser.firefox) {
|
||||
window.document.body.style.cursor = "-moz-grabbing";
|
||||
} else {
|
||||
window.document.body.style.cursor = "move";
|
||||
}
|
||||
event.preventDefault();
|
||||
|
||||
// Fire drag event ...
|
||||
screenManager.fireEvent('update');
|
||||
wasDragged = true;
|
||||
|
||||
|
||||
};
|
||||
screenManager.addEvent('mousemove', workspace._mouseMoveListener);
|
||||
|
||||
// Register mouse up listeners ...
|
||||
workspace._mouseUpListener = function (event) {
|
||||
|
||||
screenManager.removeEvent('mousemove', workspace._mouseMoveListener);
|
||||
screenManager.removeEvent('mouseup', workspace._mouseUpListener);
|
||||
workspace._mouseUpListener = null;
|
||||
workspace._mouseMoveListener = null;
|
||||
window.document.body.style.cursor = 'default';
|
||||
|
||||
// Update screen manager offset.
|
||||
var coordOrigin = workspace.getCoordOrigin();
|
||||
screenManager.setOffset(coordOrigin.x, coordOrigin.y);
|
||||
mWorkspace.enableWorkspaceEvents(true);
|
||||
|
||||
if (!wasDragged) {
|
||||
screenManager.fireEvent('click');
|
||||
}
|
||||
};
|
||||
screenManager.addEvent('mouseup', workspace._mouseUpListener);
|
||||
}
|
||||
} else {
|
||||
workspace._mouseUpListener();
|
||||
}
|
||||
};
|
||||
screenManager.addEvent('mousedown', mouseDownListener);
|
||||
},
|
||||
|
||||
setViewPort: function (size) {
|
||||
this._viewPort = size;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.commands.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');
|
||||
$assert(featureType, 'featureType can not be null');
|
||||
$assert(attributes, 'attributes can not be null');
|
||||
|
||||
this.parent();
|
||||
this._topicId = topicId;
|
||||
this._featureType = featureType;
|
||||
this._attributes = attributes;
|
||||
this._featureModel = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Overrides abstract parent method
|
||||
*/
|
||||
execute:function (commandContext) {
|
||||
var topic = commandContext.findTopics(this._topicId)[0];
|
||||
|
||||
// Feature must be created only one time.
|
||||
if (!this._featureModel) {
|
||||
var model = topic.getModel();
|
||||
this._featureModel = model.createFeature(this._featureType, this._attributes);
|
||||
}
|
||||
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);
|
||||
}
|
||||
});
|
@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.commands.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]);
|
||||
}
|
||||
});
|
@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.commands.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');
|
||||
|
||||
this.parent();
|
||||
this._models = models;
|
||||
this._parentsIds = parentTopicsId;
|
||||
},
|
||||
|
||||
/**
|
||||
* Overrides abstract parent method
|
||||
*/
|
||||
execute:function (commandContext) {
|
||||
|
||||
var me = this;
|
||||
_.each(this._models, function (model, index) {
|
||||
|
||||
// Add a new topic ...
|
||||
var topic = commandContext.createTopic(model);
|
||||
|
||||
// Connect to topic ...
|
||||
if (me._parentsIds) {
|
||||
var parentId = me._parentsIds[index];
|
||||
if ($defined(parentId)) {
|
||||
var parentTopic = commandContext.findTopics(parentId)[0];
|
||||
commandContext.connect(topic, parentTopic);
|
||||
}
|
||||
} else {
|
||||
commandContext.addTopic(topic);
|
||||
}
|
||||
|
||||
// Select just created node ...
|
||||
var designer = commandContext._designer;
|
||||
designer.onObjectFocusEvent(topic);
|
||||
topic.setOnFocus(true);
|
||||
|
||||
// Render node ...
|
||||
topic.setVisibility(true);
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Overrides abstract parent method
|
||||
* @see {@link mindplot.Command.undoExecute}
|
||||
*/
|
||||
undoExecute:function (commandContext) {
|
||||
// Delete disconnected the nodes. Create a copy of the topics ...
|
||||
var clonedModel = [];
|
||||
_.each(this._models, function (model) {
|
||||
clonedModel.push(model.clone());
|
||||
});
|
||||
|
||||
// Finally, remove the nodes ...
|
||||
_.each(this._models, function (model) {
|
||||
|
||||
var topicId = model.getId();
|
||||
var topic = commandContext.findTopics(topicId)[0];
|
||||
commandContext.deleteTopic(topic);
|
||||
});
|
||||
|
||||
this._models = clonedModel;
|
||||
}
|
||||
});
|
@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.commands.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');
|
||||
$assert($defined(attributes), 'attributes can not be null');
|
||||
|
||||
this.parent();
|
||||
this._topicId = topicId;
|
||||
this._featureId = featureId;
|
||||
this._attributes = attributes;
|
||||
},
|
||||
|
||||
/**
|
||||
* Overrides abstract parent method
|
||||
*/
|
||||
execute: function(commandContext) {
|
||||
var topic = commandContext.findTopics(this._topicId)[0];
|
||||
var feature = topic.findFeatureById(this._featureId);
|
||||
|
||||
var oldAttributes = feature.getAttributes();
|
||||
feature.setAttributes(this._attributes);
|
||||
this._attributes = oldAttributes;
|
||||
},
|
||||
|
||||
/**
|
||||
* Overrides abstract parent method
|
||||
* @see {@link mindplot.Command.undoExecute}
|
||||
*/
|
||||
undoExecute: function(commandContext) {
|
||||
this.execute(commandContext);
|
||||
}
|
||||
});
|
@ -1,183 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.commands.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');
|
||||
|
||||
this.parent();
|
||||
this._relIds = relIds;
|
||||
this._topicIds = topicIds;
|
||||
this._deletedTopicModels = [];
|
||||
this._deletedRelModel = [];
|
||||
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 ...
|
||||
var topics = this._filterChildren(this._topicIds, commandContext);
|
||||
|
||||
if (topics.length > 0) {
|
||||
_.each(topics, function (topic) {
|
||||
// In case that it's editing text node, force close without update ...
|
||||
topic.closeEditors();
|
||||
|
||||
var model = topic.getModel();
|
||||
|
||||
// Delete relationships
|
||||
var relationships = this._collectInDepthRelationships(topic);
|
||||
this._deletedRelModel.append(relationships.map(function (rel) {
|
||||
return rel.getModel().clone();
|
||||
}));
|
||||
|
||||
_.each(relationships, function (relationship) {
|
||||
commandContext.deleteRelationship(relationship);
|
||||
});
|
||||
|
||||
// Store information for undo ...
|
||||
var clonedModel = model.clone();
|
||||
this._deletedTopicModels.push(clonedModel);
|
||||
var outTopic = topic.getOutgoingConnectedTopic();
|
||||
var outTopicId = null;
|
||||
if (outTopic != null) {
|
||||
outTopicId = outTopic.getId();
|
||||
}
|
||||
this._parentTopicIds.push(outTopicId);
|
||||
|
||||
// Finally, delete the topic from the workspace...
|
||||
commandContext.deleteTopic(topic);
|
||||
|
||||
}, this);
|
||||
}
|
||||
|
||||
var rels = commandContext.findRelationships(this._relIds);
|
||||
if (rels.length > 0) {
|
||||
_.each(rels, function (rel) {
|
||||
this._deletedRelModel.push(rel.getModel().clone());
|
||||
commandContext.deleteRelationship(rel);
|
||||
}, this);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Overrides abstract parent method
|
||||
* @see {@link mindplot.Command.undoExecute}
|
||||
*/
|
||||
undoExecute:function (commandContext) {
|
||||
|
||||
// Add all the topics ...
|
||||
_.each(this._deletedTopicModels, function (model) {
|
||||
commandContext.createTopic(model);
|
||||
}, this);
|
||||
|
||||
// Do they need to be connected ?
|
||||
_.each(this._deletedTopicModels, function (topicModel, index) {
|
||||
var topics = commandContext.findTopics(topicModel.getId());
|
||||
|
||||
var parentId = this._parentTopicIds[index];
|
||||
if (parentId) {
|
||||
var parentTopics = commandContext.findTopics(parentId);
|
||||
commandContext.connect(topics[0], parentTopics[0]);
|
||||
}
|
||||
}, this);
|
||||
|
||||
// Add rebuild relationships ...
|
||||
_.each(this._deletedRelModel, function (model) {
|
||||
commandContext.addRelationship(model);
|
||||
});
|
||||
|
||||
// Finally display the topics ...
|
||||
_.each(this._deletedTopicModels, function (topicModel) {
|
||||
var topics = commandContext.findTopics(topicModel.getId());
|
||||
topics[0].setBranchVisibility(true);
|
||||
}, this);
|
||||
|
||||
// Focus on last recovered topic ..
|
||||
if (this._deletedTopicModels.length > 0) {
|
||||
var firstTopic = this._deletedTopicModels[0];
|
||||
var topic = commandContext.findTopics(firstTopic.getId())[0];
|
||||
topic.setOnFocus(true);
|
||||
}
|
||||
|
||||
this._deletedTopicModels = [];
|
||||
this._parentTopicIds = [];
|
||||
this._deletedRelModel = [];
|
||||
},
|
||||
|
||||
_filterChildren:function (topicIds, commandContext) {
|
||||
var topics = commandContext.findTopics(topicIds);
|
||||
|
||||
var result = [];
|
||||
_.each(topics, function (topic) {
|
||||
var parent = topic.getParent();
|
||||
var found = false;
|
||||
while (parent != null && !found) {
|
||||
found = topicIds.contains(parent.getId());
|
||||
if (found) {
|
||||
break;
|
||||
}
|
||||
parent = parent.getParent();
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
result.push(topic);
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
_collectInDepthRelationships:function (topic) {
|
||||
var result = [];
|
||||
result.append(topic.getRelationships());
|
||||
|
||||
var children = topic.getChildren();
|
||||
var rels = children.map(function (topic) {
|
||||
return this._collectInDepthRelationships(topic);
|
||||
}, this);
|
||||
result.append(rels.flatten());
|
||||
|
||||
if (result.length > 0) {
|
||||
// Filter for unique ...
|
||||
result = result.sort(function (a, b) {
|
||||
return a.getModel().getId() - b.getModel().getId();
|
||||
});
|
||||
var ret = [result[0]];
|
||||
for (var i = 1; i < result.length; i++) { // start loop at 1 as element 0 can never be a duplicate
|
||||
if (result[i - 1] !== result[i]) {
|
||||
ret.push(result[i]);
|
||||
}
|
||||
}
|
||||
result = ret;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
});
|
@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.commands.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");
|
||||
|
||||
this._topicsId = topicId;
|
||||
if ($defined(parentTopic))
|
||||
this._parentId = parentTopic.getId();
|
||||
|
||||
this.parent();
|
||||
this._position = position;
|
||||
this._order = order;
|
||||
},
|
||||
|
||||
/**
|
||||
* Overrides abstract parent method
|
||||
*/
|
||||
execute:function (commandContext) {
|
||||
|
||||
var topic = commandContext.findTopics(this._topicsId)[0];
|
||||
topic.setVisibility(false);
|
||||
|
||||
// Save old position ...
|
||||
var origParentTopic = topic.getOutgoingConnectedTopic();
|
||||
|
||||
// In this case, topics are positioned using order ...
|
||||
var origOrder = topic.getOrder();
|
||||
var origPosition = topic.getPosition();
|
||||
|
||||
// Disconnect topic ..
|
||||
if ($defined(origParentTopic) && origParentTopic != this._parentId) {
|
||||
commandContext.disconnect(topic);
|
||||
}
|
||||
|
||||
// Set topic order ...
|
||||
if (this._order != null) {
|
||||
topic.setOrder(this._order);
|
||||
} else if (this._position != null) {
|
||||
commandContext.moveTopic(topic, this._position);
|
||||
} else {
|
||||
$assert("Illegal command state exception.");
|
||||
}
|
||||
|
||||
// Finally, connect topic ...
|
||||
if (origParentTopic != this._parentId) {
|
||||
|
||||
if ($defined(this._parentId)) {
|
||||
var parentTopic = commandContext.findTopics(this._parentId)[0];
|
||||
commandContext.connect(topic, parentTopic);
|
||||
}
|
||||
|
||||
// Backup old parent id ...
|
||||
this._parentId = null;
|
||||
if ($defined(origParentTopic)) {
|
||||
this._parentId = origParentTopic.getId();
|
||||
}
|
||||
}
|
||||
topic.setVisibility(true);
|
||||
|
||||
// Store for undo ...
|
||||
this._order = origOrder;
|
||||
this._position = origPosition;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Overrides abstract parent method
|
||||
* @see {@link mindplot.Command.undoExecute}
|
||||
*/
|
||||
undoExecute:function (commandContext) {
|
||||
this.execute(commandContext);
|
||||
}
|
||||
});
|
@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.commands.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] 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");
|
||||
|
||||
this.parent();
|
||||
this._value = value;
|
||||
this._topicsId = topicsIds;
|
||||
this._commandFunc = commandFunc;
|
||||
this._oldValues = [];
|
||||
},
|
||||
|
||||
/**
|
||||
* Overrides abstract parent method
|
||||
*/
|
||||
execute:function (commandContext) {
|
||||
if (!this.applied) {
|
||||
|
||||
var topics = null;
|
||||
try {
|
||||
topics = commandContext.findTopics(this._topicsId);
|
||||
} catch (e) {
|
||||
if (this._commandFunc.commandType != "changeTextToTopic") {
|
||||
// Workaround: For some reason, there is a combination of events that involves
|
||||
// making some modification and firing out of focus event. This is causing
|
||||
// that a remove node try to be removed. In some other life, I will come with the solution.
|
||||
// Almost aways occurs with IE9. I could be related with some change of order in sets o something similar.
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
if (topics != null) {
|
||||
var me = this;
|
||||
_.each(topics, function (topic) {
|
||||
var oldValue = me._commandFunc(topic, me._value);
|
||||
me._oldValues.push(oldValue);
|
||||
});
|
||||
}
|
||||
this.applied = true;
|
||||
|
||||
} else {
|
||||
throw "Command can not be applied two times in a row.";
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Overrides abstract parent method
|
||||
* @see {@link mindplot.Command.undoExecute}
|
||||
*/
|
||||
undoExecute:function (commandContext) {
|
||||
if (this.applied) {
|
||||
var topics = commandContext.findTopics(this._topicsId);
|
||||
var me = this;
|
||||
_.each(topics, function (topic, index) {
|
||||
me._commandFunc(topic, me._oldValues[index]);
|
||||
|
||||
});
|
||||
|
||||
this.applied = false;
|
||||
this._oldValues = [];
|
||||
} else {
|
||||
throw "undo can not be applied.";
|
||||
}
|
||||
}
|
||||
});
|
@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.commands.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');
|
||||
|
||||
this.parent();
|
||||
this._ctrlPointControler = ctrlPointController;
|
||||
this._line = ctrlPointController._line;
|
||||
this._controlPoint = this._ctrlPointControler.getControlPoint(point).clone();
|
||||
this._oldControlPoint = this._ctrlPointControler.getOriginalCtrlPoint(point).clone();
|
||||
this._originalEndPoint = this._ctrlPointControler.getOriginalEndPoint(point).clone();
|
||||
switch (point) {
|
||||
case 0:
|
||||
this._wasCustom = this._line.getLine().isSrcControlPointCustom();
|
||||
this._endPoint = this._line.getLine().getFrom().clone();
|
||||
break;
|
||||
case 1:
|
||||
this._wasCustom = this._line.getLine().isDestControlPointCustom();
|
||||
this._endPoint = this._line.getLine().getTo().clone();
|
||||
break;
|
||||
}
|
||||
this._point = point;
|
||||
},
|
||||
|
||||
/**
|
||||
* Overrides abstract parent method
|
||||
*/
|
||||
execute:function (commandContext) {
|
||||
var model = this._line.getModel();
|
||||
switch (this._point) {
|
||||
case 0:
|
||||
model.setSrcCtrlPoint(this._controlPoint.clone());
|
||||
this._line.setFrom(this._endPoint.x, this._endPoint.y);
|
||||
this._line.setIsSrcControlPointCustom(true);
|
||||
this._line.setSrcControlPoint(this._controlPoint.clone());
|
||||
break;
|
||||
case 1:
|
||||
model.setDestCtrlPoint(this._controlPoint.clone());
|
||||
this._wasCustom = this._line.getLine().isDestControlPointCustom();
|
||||
this._line.setTo(this._endPoint.x, this._endPoint.y);
|
||||
this._line.setIsDestControlPointCustom(true);
|
||||
this._line.setDestControlPoint(this._controlPoint.clone());
|
||||
break;
|
||||
}
|
||||
if (this._line.isOnFocus()) {
|
||||
this._line._refreshShape();
|
||||
this._ctrlPointControler.setLine(this._line);
|
||||
}
|
||||
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();
|
||||
switch (this._point) {
|
||||
case 0:
|
||||
if ($defined(this._oldControlPoint)) {
|
||||
line.setFrom(this._originalEndPoint.x, this._originalEndPoint.y);
|
||||
model.setSrcCtrlPoint(this._oldControlPoint.clone());
|
||||
line.setSrcControlPoint(this._oldControlPoint.clone());
|
||||
line.setIsSrcControlPointCustom(this._wasCustom);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if ($defined(this._oldControlPoint)) {
|
||||
line.setTo(this._originalEndPoint.x, this._originalEndPoint.y);
|
||||
model.setDestCtrlPoint(this._oldControlPoint.clone());
|
||||
line.setDestControlPoint(this._oldControlPoint.clone());
|
||||
line.setIsDestControlPointCustom(this._wasCustom);
|
||||
}
|
||||
break;
|
||||
}
|
||||
this._line.getLine().updateLine(this._point);
|
||||
if (this._line.isOnFocus()) {
|
||||
this._ctrlPointControler.setLine(line);
|
||||
line._refreshShape();
|
||||
}
|
||||
}
|
||||
});
|
@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.commands.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');
|
||||
|
||||
this.parent();
|
||||
this._topicId = topicId;
|
||||
this._featureId = featureId;
|
||||
this._oldFeature = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Overrides abstract parent method
|
||||
*/
|
||||
execute:function (commandContext) {
|
||||
var topic = commandContext.findTopics(this._topicId)[0];
|
||||
var feature = topic.findFeatureById(this._featureId);
|
||||
topic.removeFeature(feature);
|
||||
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);
|
||||
this._oldFeature = null;
|
||||
}
|
||||
});
|
@ -1,5 +0,0 @@
|
||||
try {
|
||||
$(document).trigger('loadcomplete', 'mind');
|
||||
} catch (e) {
|
||||
console.error(e.stack);
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
var mindplot = {};
|
||||
mindplot.util = {};
|
||||
mindplot.commands = {};
|
||||
mindplot.layout = {};
|
||||
mindplot.layout.boards = {};
|
||||
mindplot.layout.boards.original = {};
|
||||
mindplot.widget = {};
|
||||
mindplot.model = {};
|
||||
mindplot.collaboration = {};
|
||||
mindplot.collaboration.framework = {};
|
||||
mindplot.persistence = {};
|
||||
|
||||
mindplot.layout = {};
|
||||
|
||||
Class.Mutators.Static = function (items) {
|
||||
this.extend(items);
|
||||
};
|
||||
|
@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @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);
|
||||
return result;
|
||||
},
|
||||
|
||||
_getVerticalPadding: function() {
|
||||
return mindplot.layout.AbstractBasicSorter.INTERNODE_VERTICAL_PADDING;
|
||||
},
|
||||
|
||||
_computeChildrenHeight : function(treeSet, node, heightCache) {
|
||||
var height = node.getSize().height + (this._getVerticalPadding() * 2); // 2* Top and down padding;
|
||||
|
||||
var result;
|
||||
var children = treeSet.getChildren(node);
|
||||
if (children.length == 0 || node.areChildrenShrunken()) {
|
||||
result = height;
|
||||
} else {
|
||||
var childrenHeight = 0;
|
||||
_.each(children, function(child) {
|
||||
childrenHeight += this._computeChildrenHeight(treeSet, child, heightCache);
|
||||
}, this);
|
||||
|
||||
result = Math.max(height, childrenHeight);
|
||||
}
|
||||
|
||||
if (heightCache) {
|
||||
heightCache[node.getId()] = result;
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
_getSortedChildren:function(treeSet, node) {
|
||||
var result = treeSet.getChildren(node);
|
||||
result.sort(function(a, b) {
|
||||
return a.getOrder() - b.getOrder()
|
||||
});
|
||||
return result;
|
||||
},
|
||||
|
||||
_getRelativeDirection: function(reference, position) {
|
||||
var offset = position.x - reference.x;
|
||||
return offset >= 0 ? 1 : -1;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* @constant
|
||||
* @type {Number}
|
||||
* @default
|
||||
*/
|
||||
mindplot.layout.AbstractBasicSorter.INTERNODE_VERTICAL_PADDING = 5;
|
||||
/**
|
||||
* @constant
|
||||
* @type {Number}
|
||||
* @default
|
||||
*/
|
||||
mindplot.layout.AbstractBasicSorter.INTERNODE_HORIZONTAL_PADDING = 30;
|
@ -1,275 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.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) {
|
||||
$assert($defined(position), "position cannot be null for predict in free positioning");
|
||||
$assert($defined(node), "node cannot be null for predict in free positioning");
|
||||
|
||||
var rootNode = graph.getRootNode(parent);
|
||||
var direction = this._getRelativeDirection(rootNode.getPosition(), node.getPosition());
|
||||
|
||||
var limitXPos = parent.getPosition().x + direction * (parent.getSize().width / 2 + node.getSize().width / 2 + mindplot.layout.BalancedSorter.INTERNODE_HORIZONTAL_PADDING);
|
||||
|
||||
var xPos = direction > 0 ?
|
||||
(position.x >= limitXPos ? position.x : limitXPos) :
|
||||
(position.x <= limitXPos ? position.x : limitXPos);
|
||||
|
||||
return [0, {x:xPos, y:position.y}];
|
||||
}
|
||||
|
||||
var rootNode = graph.getRootNode(parent);
|
||||
|
||||
// If it is a dragged node...
|
||||
if (node) {
|
||||
$assert($defined(position), "position cannot be null for predict in dragging");
|
||||
var nodeDirection = this._getRelativeDirection(rootNode.getPosition(), node.getPosition());
|
||||
var positionDirection = this._getRelativeDirection(rootNode.getPosition(), position);
|
||||
var siblings = graph.getSiblings(node);
|
||||
|
||||
var sameParent = parent == graph.getParent(node);
|
||||
if (siblings.length == 0 && nodeDirection == positionDirection && sameParent) {
|
||||
return [node.getOrder(), node.getPosition()];
|
||||
}
|
||||
}
|
||||
|
||||
if (!position) {
|
||||
var right = this._getChildrenForOrder(parent, graph, 0);
|
||||
var left = this._getChildrenForOrder(parent, graph, 1);
|
||||
}
|
||||
// Filter nodes on one side..
|
||||
var order = position ? (position.x > rootNode.getPosition().x ? 0 : 1) : ((right.length - left.length) > 0 ? 1 : 0);
|
||||
var direction = order % 2 == 0 ? 1 : -1;
|
||||
|
||||
// Exclude the dragged node (if set)
|
||||
var children = this._getChildrenForOrder(parent, graph, order).filter(function (child) {
|
||||
return child != node;
|
||||
});
|
||||
|
||||
// No children?
|
||||
if (children.length == 0) {
|
||||
return [order, {x:parent.getPosition().x + direction * (parent.getSize().width / 2 + mindplot.layout.BalancedSorter.INTERNODE_HORIZONTAL_PADDING * 2), y:parent.getPosition().y}];
|
||||
}
|
||||
|
||||
// Try to fit within ...
|
||||
var result = null;
|
||||
var last = children.getLast();
|
||||
position = position || {x:last.getPosition().x, y:last.getPosition().y + 1};
|
||||
_.each(children, function (child, index) {
|
||||
var cpos = child.getPosition();
|
||||
if (position.y > cpos.y) {
|
||||
yOffset = child == last ?
|
||||
child.getSize().height + mindplot.layout.BalancedSorter.INTERNODE_VERTICAL_PADDING * 2 :
|
||||
(children[index + 1].getPosition().y - child.getPosition().y) / 2;
|
||||
result = [child.getOrder() + 2, {x:cpos.x, y:cpos.y + yOffset}];
|
||||
}
|
||||
});
|
||||
|
||||
// Position wasn't below any node, so it must be inserted above
|
||||
if (!result) {
|
||||
var first = children[0];
|
||||
result = [position.x > 0 ? 0 : 1, {
|
||||
x:first.getPosition().x,
|
||||
y:first.getPosition().y - first.getSize().height - mindplot.layout.BalancedSorter.INTERNODE_VERTICAL_PADDING * 2
|
||||
}];
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {} treeSet
|
||||
* @param {} parent
|
||||
* @param {} child
|
||||
* @param {} order
|
||||
*/
|
||||
insert:function (treeSet, parent, child, order) {
|
||||
var children = this._getChildrenForOrder(parent, treeSet, order);
|
||||
|
||||
// If no children, return 0 or 1 depending on the side
|
||||
if (children.length == 0) {
|
||||
child.setOrder(order % 2);
|
||||
return;
|
||||
}
|
||||
|
||||
// Shift all the elements by two, so side is the same.
|
||||
// In case of balanced sorter, order don't need to be continuous...
|
||||
var max = 0;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var node = children[i];
|
||||
max = Math.max(max, node.getOrder());
|
||||
if (node.getOrder() >= order) {
|
||||
max = Math.max(max, node.getOrder() + 2);
|
||||
node.setOrder(node.getOrder() + 2);
|
||||
}
|
||||
}
|
||||
|
||||
var newOrder = order > (max + 1) ? (max + 2) : order;
|
||||
child.setOrder(newOrder);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {} treeSet
|
||||
* @param {} node
|
||||
*/
|
||||
detach:function (treeSet, node) {
|
||||
var parent = treeSet.getParent(node);
|
||||
// Filter nodes on one side..
|
||||
var children = this._getChildrenForOrder(parent, treeSet, node.getOrder());
|
||||
|
||||
_.each(children, function (child, index) {
|
||||
if (child.getOrder() > node.getOrder()) {
|
||||
child.setOrder(child.getOrder() - 2);
|
||||
}
|
||||
});
|
||||
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.");
|
||||
|
||||
var children = this._getSortedChildren(treeSet, node);
|
||||
|
||||
// Compute heights ...
|
||||
var heights = children.map(
|
||||
function (child) {
|
||||
return {id:child.getId(), order:child.getOrder(), width:child.getSize().width, height:this._computeChildrenHeight(treeSet, child)};
|
||||
}, this).reverse();
|
||||
|
||||
|
||||
// Compute the center of the branch ...
|
||||
var totalPHeight = 0;
|
||||
var totalNHeight = 0;
|
||||
|
||||
_.each(heights, function (elem) {
|
||||
if (elem.order % 2 == 0) {
|
||||
totalPHeight += elem.height;
|
||||
} else {
|
||||
totalNHeight += elem.height;
|
||||
}
|
||||
});
|
||||
var psum = totalPHeight / 2;
|
||||
var nsum = totalNHeight / 2;
|
||||
var ysum = 0;
|
||||
|
||||
// Calculate the offsets ...
|
||||
var result = {};
|
||||
for (var i = 0; i < heights.length; i++) {
|
||||
var direction = heights[i].order % 2 ? -1 : 1;
|
||||
|
||||
if (direction > 0) {
|
||||
psum = psum - heights[i].height;
|
||||
ysum = psum;
|
||||
} else {
|
||||
nsum = nsum - heights[i].height;
|
||||
ysum = nsum;
|
||||
}
|
||||
|
||||
var yOffset = ysum + heights[i].height / 2;
|
||||
var xOffset = direction * (node.getSize().width / 2 + heights[i].width / 2 + +mindplot.layout.BalancedSorter.INTERNODE_HORIZONTAL_PADDING);
|
||||
|
||||
$assert(!isNaN(xOffset), "xOffset can not be null");
|
||||
$assert(!isNaN(yOffset), "yOffset can not be null");
|
||||
|
||||
result[heights[i].id] = {x:xOffset, y:yOffset};
|
||||
}
|
||||
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());
|
||||
|
||||
// All odd ordered nodes should be "continuous" by themselves
|
||||
// All even numbered nodes should be "continuous" by themselves
|
||||
var factor = node.getOrder() % 2 == 0 ? 2 : 1;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var order = i == 0 && factor == 1 ? 1 : (factor * i);
|
||||
$assert(children[i].getOrder() == order, "Missing order elements. Missing order: " + (i * factor) + ". Parent:" + node.getId() + ",Node:" + children[i].getId());
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @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";
|
||||
},
|
||||
|
||||
_getChildrenForOrder:function (parent, graph, order) {
|
||||
return this._getSortedChildren(graph, parent).filter(function (child) {
|
||||
return child.getOrder() % 2 == order % 2;
|
||||
});
|
||||
},
|
||||
|
||||
_getVerticalPadding:function () {
|
||||
return mindplot.layout.BalancedSorter.INTERNODE_VERTICAL_PADDING;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @constant
|
||||
* @type {Number}
|
||||
* @default
|
||||
*/
|
||||
mindplot.layout.BalancedSorter.INTERNODE_VERTICAL_PADDING = 5;
|
||||
/**
|
||||
* @constant
|
||||
* @type {Number}
|
||||
* @default
|
||||
*/
|
||||
mindplot.layout.BalancedSorter.INTERNODE_HORIZONTAL_PADDING = 30;
|
@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.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;
|
||||
this._position = null;
|
||||
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 + "}]";
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.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";
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.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',
|
||||
NodeShrinkEvent:'NodeShrinkEvent',
|
||||
NodeConnectEvent:'NodeConnectEvent',
|
||||
NodeDisconnectEvent:'NodeDisconnectEvent',
|
||||
NodeAdded:'NodeAdded',
|
||||
NodeRemoved:'NodeRemoved',
|
||||
DoLayout:'DoLayout'
|
||||
};
|
||||
|
||||
/** instance */
|
||||
mindplot.EventBus.instance = new mindplot.EventBus();
|
@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.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));
|
||||
mindplot.EventBus.instance.addEvent(mindplot.EventBus.events.NodeResizeEvent, this._nodeResizeEvent.bind(this));
|
||||
mindplot.EventBus.instance.addEvent(mindplot.EventBus.events.NodeMoveEvent, this._nodeMoveEvent.bind(this));
|
||||
mindplot.EventBus.instance.addEvent(mindplot.EventBus.events.NodeDisconnectEvent, this._nodeDisconnectEvent.bind(this));
|
||||
mindplot.EventBus.instance.addEvent(mindplot.EventBus.events.NodeConnectEvent, this._nodeConnectEvent.bind(this));
|
||||
mindplot.EventBus.instance.addEvent(mindplot.EventBus.events.NodeShrinkEvent, this._nodeShrinkEvent.bind(this));
|
||||
mindplot.EventBus.instance.addEvent(mindplot.EventBus.events.DoLayout, this._doLayout.bind(this));
|
||||
},
|
||||
|
||||
_nodeResizeEvent: function(args) {
|
||||
this._layoutManager.updateNodeSize(args.node.getId(), args.size);
|
||||
},
|
||||
|
||||
_nodeMoveEvent: function(args) {
|
||||
this._layoutManager.moveNode(args.node.getId(), args.position);
|
||||
},
|
||||
|
||||
_nodeDisconnectEvent: function(node) {
|
||||
this._layoutManager.disconnectNode(node.getId());
|
||||
},
|
||||
|
||||
_nodeConnectEvent: function(args) {
|
||||
this._layoutManager.connectNode(args.parentNode.getId(), args.childNode.getId(), args.childNode.getOrder());
|
||||
|
||||
},
|
||||
|
||||
_nodeShrinkEvent: function(node) {
|
||||
this._layoutManager.updateShrinkState(node.getId(), node.areChildrenShrunken());
|
||||
},
|
||||
|
||||
_nodeAdded: function(node) {
|
||||
// Central topic must not be added twice ...
|
||||
if (node.getId() != 0) {
|
||||
this._layoutManager.addNode(node.getId(), {width:10,height:10}, node.getPosition());
|
||||
this._layoutManager.updateShrinkState(node.getId(), node.areChildrenShrunken());
|
||||
}
|
||||
},
|
||||
|
||||
_nodeRemoved: function(node) {
|
||||
this._layoutManager.removeNode(node.getId());
|
||||
},
|
||||
|
||||
_doLayout: function() {
|
||||
// (function() {
|
||||
this._layoutManager.layout(true);
|
||||
// console.log("---------");
|
||||
// this._layoutManager.dump();
|
||||
// console.log("---------");
|
||||
// console.log("---------");
|
||||
// }).delay(0, this);
|
||||
},
|
||||
|
||||
/** @return layout manager */
|
||||
getLayoutManager: function() {
|
||||
return this._layoutManager;
|
||||
}
|
||||
|
||||
});
|
@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @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.");
|
||||
$assert("order can no be null.");
|
||||
|
||||
var children = this._getSortedChildren(treeSet, node);
|
||||
|
||||
// Compute heights ...
|
||||
var me = this;
|
||||
var heights = children.map(function(child) {
|
||||
return {
|
||||
id: child.getId(),
|
||||
height: me._computeChildrenHeight(treeSet, child)
|
||||
};
|
||||
});
|
||||
|
||||
// Calculate the offsets ...
|
||||
var result = {};
|
||||
for (var i = 0; i < heights.length; i++) {
|
||||
var even = i%2 == 0 ? 1 : -1;
|
||||
|
||||
var zeroHeight = i == 0 ? 0 : heights[0].height/2 * even;
|
||||
var middleHeight = 0;
|
||||
for (var j=i-2; j>0; j=j-2) {
|
||||
middleHeight += heights[j].height * even;
|
||||
}
|
||||
var finalHeight = i == 0 ? 0 : heights[i].height/2 * even;
|
||||
|
||||
var yOffset = zeroHeight + middleHeight +finalHeight;
|
||||
var xOffset = node.getSize().width + mindplot.layout.GridSorter.GRID_HORIZONTAR_SIZE;
|
||||
|
||||
$assert(!isNaN(xOffset), "xOffset can not be null");
|
||||
$assert(!isNaN(yOffset), "yOffset can not be null");
|
||||
|
||||
result[heights[i].id] = {x:xOffset,y:yOffset};
|
||||
|
||||
}
|
||||
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;
|
||||
|
@ -1,266 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.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");
|
||||
var position = position || {x:0, y:0};
|
||||
|
||||
this._treeSet = new mindplot.layout.RootedTreeSet();
|
||||
this._layout = new mindplot.layout.OriginalLayout(this._treeSet);
|
||||
|
||||
var rootNode = this._layout.createNode(rootNodeId, rootSize, position, 'root');
|
||||
this._treeSet.setRoot(rootNode);
|
||||
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");
|
||||
|
||||
var node = this._treeSet.find(id);
|
||||
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");
|
||||
|
||||
var node = this._treeSet.find(id);
|
||||
node.setShrunken(value);
|
||||
|
||||
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");
|
||||
$assert($defined(position.x), "x can not be null");
|
||||
$assert($defined(position.y), "y can not be null");
|
||||
|
||||
var node = this._treeSet.find(id);
|
||||
// @Todo: this should not be here. This is broking the isolated node support...
|
||||
// node.setFree(true);
|
||||
// node.setFreeDisplacement({x:position.x - node.getPosition().x, y:position.y - node.getPosition().y});
|
||||
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");
|
||||
$assert($defined(order), "order cannot be null");
|
||||
|
||||
this._layout.connectNode(parentId, childId, order);
|
||||
|
||||
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);
|
||||
|
||||
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');
|
||||
this._treeSet.add(result);
|
||||
|
||||
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);
|
||||
|
||||
// Is It connected ?
|
||||
if (this._treeSet.getParent(node)) {
|
||||
this.disconnectNode(id);
|
||||
}
|
||||
|
||||
// Remove the all the branch ...
|
||||
this._treeSet.remove(id);
|
||||
|
||||
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");
|
||||
|
||||
var parent = this._treeSet.find(parentId);
|
||||
var node = nodeId ? this._treeSet.find(nodeId) : null;
|
||||
var sorter = parent.getSorter();
|
||||
|
||||
var result = sorter.predict(this._treeSet, parent, node, position, free);
|
||||
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};
|
||||
var squaresize = 10;
|
||||
var canvas = Raphael(containerId, size.width, size.height);
|
||||
canvas.drawGrid(0, 0, size.width, size.height, size.width / squaresize, size.height / squaresize);
|
||||
this._treeSet.plot(canvas);
|
||||
|
||||
return canvas;
|
||||
},
|
||||
|
||||
/**
|
||||
* initializes the layout to be updated
|
||||
* @param fireEvents
|
||||
* @return this
|
||||
*/
|
||||
layout: function(fireEvents) {
|
||||
// File repositioning ...
|
||||
this._layout.layout();
|
||||
|
||||
// Collect changes ...
|
||||
this._collectChanges();
|
||||
|
||||
if ($(fireEvents).length>0 || fireEvents) {
|
||||
this._flushEvents();
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
_flushEvents: function() {
|
||||
_.each(this._events, function(event) {
|
||||
this.fireEvent('change', event);
|
||||
}, this);
|
||||
this._events = [];
|
||||
},
|
||||
|
||||
_collectChanges: function(nodes) {
|
||||
if (!nodes)
|
||||
nodes = this._treeSet.getTreeRoots();
|
||||
|
||||
_.each(nodes, function(node) {
|
||||
if (node.hasOrderChanged() || node.hasPositionChanged()) {
|
||||
|
||||
// Find or create a event ...
|
||||
var id = node.getId();
|
||||
var event = this._events.some(function(event) {
|
||||
return event.id == id;
|
||||
});
|
||||
if (!event) {
|
||||
event = new mindplot.layout.ChangeEvent(id);
|
||||
}
|
||||
|
||||
// Update nodes ...
|
||||
event.setOrder(node.getOrder());
|
||||
event.setPosition(node.getPosition());
|
||||
|
||||
node.resetPositionState();
|
||||
node.resetOrderState();
|
||||
node.resetFreeState();
|
||||
this._events.push(event);
|
||||
}
|
||||
this._collectChanges(this._treeSet.getChildren(node));
|
||||
}, this);
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -1,221 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.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");
|
||||
$assert(position, "position can not be null");
|
||||
$assert(sorter, "sorter can not be null");
|
||||
|
||||
this._id = id;
|
||||
this._sorter = sorter;
|
||||
this._properties = {};
|
||||
|
||||
this.setSize(size);
|
||||
this.setPosition(position);
|
||||
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) {
|
||||
prop.hasChanged = false;
|
||||
}
|
||||
},
|
||||
|
||||
/** */
|
||||
resetOrderState:function () {
|
||||
var prop = this._properties['order'];
|
||||
if (prop) {
|
||||
prop.hasChanged = false;
|
||||
}
|
||||
},
|
||||
|
||||
/** */
|
||||
resetFreeState:function () {
|
||||
var prop = this._properties['freeDisplacement'];
|
||||
if (prop) {
|
||||
prop.hasChanged = false;
|
||||
}
|
||||
},
|
||||
|
||||
/** */
|
||||
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");
|
||||
$assert($defined(displacement.y), "y can not be null");
|
||||
var oldDisplacement = this.getFreeDisplacement();
|
||||
var newDisplacement = {x:oldDisplacement.x + displacement.x, y:oldDisplacement.y + displacement.y};
|
||||
|
||||
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");
|
||||
$assert($defined(position.y), "y can not be null");
|
||||
|
||||
// This is a performance improvement to avoid movements that really could be avoided.
|
||||
var currentPos = this.getPosition();
|
||||
if (currentPos == null || Math.abs(currentPos.x - position.x) > 2 || Math.abs(currentPos.y - position.y) > 2)
|
||||
this._setProperty('position', position);
|
||||
},
|
||||
|
||||
_setProperty:function (key, value) {
|
||||
var prop = this._properties[key];
|
||||
if (!prop) {
|
||||
prop = {
|
||||
hasChanged:false,
|
||||
value:null,
|
||||
oldValue:null
|
||||
};
|
||||
}
|
||||
|
||||
// Only update if the property has changed ...
|
||||
if (JSON.stringify(prop.value) != JSON.stringify(value)) {
|
||||
prop.oldValue = prop.value;
|
||||
prop.value = value;
|
||||
prop.hasChanged = true;
|
||||
}
|
||||
this._properties[key] = prop;
|
||||
},
|
||||
|
||||
_getProperty:function (key) {
|
||||
var prop = this._properties[key];
|
||||
return $defined(prop) ? prop.value : null;
|
||||
},
|
||||
|
||||
_isPropertyChanged:function (key) {
|
||||
var prop = this._properties[key];
|
||||
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() + "]";
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -1,256 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.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");
|
||||
$assert(position, "position can not be null");
|
||||
$assert(type, "type can not be null");
|
||||
|
||||
var strategy = type === 'root' ?
|
||||
mindplot.layout.OriginalLayout.BALANCED_SORTER :
|
||||
mindplot.layout.OriginalLayout.SYMMETRIC_SORTER;
|
||||
return new mindplot.layout.Node(id, size, position, strategy);
|
||||
},
|
||||
|
||||
/** */
|
||||
connectNode:function (parentId, childId, order) {
|
||||
|
||||
var parent = this._treeSet.find(parentId);
|
||||
var child = this._treeSet.find(childId);
|
||||
|
||||
// Insert the new node ...
|
||||
var sorter = parent.getSorter();
|
||||
sorter.insert(this._treeSet, parent, child, order);
|
||||
|
||||
// Connect the new node ...
|
||||
this._treeSet.connect(parentId, childId);
|
||||
|
||||
// Fire a basic validation ...
|
||||
sorter.verify(this._treeSet, parent);
|
||||
},
|
||||
|
||||
/** */
|
||||
disconnectNode:function (nodeId) {
|
||||
var node = this._treeSet.find(nodeId);
|
||||
var parent = this._treeSet.getParent(node);
|
||||
$assert(parent, "Node already disconnected");
|
||||
|
||||
// Make it fixed
|
||||
node.setFree(false);
|
||||
node.resetFreeDisplacement();
|
||||
|
||||
// Remove from children list.
|
||||
var sorter = parent.getSorter();
|
||||
sorter.detach(this._treeSet, node);
|
||||
|
||||
// Disconnect the new node ...
|
||||
this._treeSet.disconnect(nodeId);
|
||||
|
||||
// Fire a basic validation ...
|
||||
parent.getSorter().verify(this._treeSet, parent);
|
||||
},
|
||||
|
||||
/** */
|
||||
layout:function () {
|
||||
var roots = this._treeSet.getTreeRoots();
|
||||
_.each(roots, function (node) {
|
||||
|
||||
// Calculate all node heights ...
|
||||
var sorter = node.getSorter();
|
||||
|
||||
var heightById = sorter.computeChildrenIdByHeights(this._treeSet, node);
|
||||
|
||||
this._layoutChildren(node, heightById);
|
||||
|
||||
this._fixOverlapping(node, heightById);
|
||||
}, this);
|
||||
},
|
||||
|
||||
_layoutChildren:function (node, heightById) {
|
||||
|
||||
var nodeId = node.getId();
|
||||
var children = this._treeSet.getChildren(node);
|
||||
var parent = this._treeSet.getParent(node);
|
||||
var childrenOrderMoved = children.some(function (child) {
|
||||
return child.hasOrderChanged();
|
||||
});
|
||||
var childrenSizeChanged = children.some(function (child) {
|
||||
return child.hasSizeChanged();
|
||||
});
|
||||
|
||||
// If ether any of the nodes has been changed of position or the height of the children is not
|
||||
// the same, children nodes must be repositioned ....
|
||||
var newBranchHeight = heightById[nodeId];
|
||||
|
||||
var parentHeightChanged = $defined(parent) ? parent._heightChanged : false;
|
||||
var heightChanged = node._branchHeight != newBranchHeight;
|
||||
node._heightChanged = heightChanged || parentHeightChanged;
|
||||
|
||||
if (childrenOrderMoved || childrenSizeChanged || heightChanged || parentHeightChanged) {
|
||||
var sorter = node.getSorter();
|
||||
var offsetById = sorter.computeOffsets(this._treeSet, node);
|
||||
var parentPosition = node.getPosition();
|
||||
var me = this;
|
||||
_.each(children, function (child) {
|
||||
var offset = offsetById[child.getId()];
|
||||
|
||||
var childFreeDisplacement = child.getFreeDisplacement();
|
||||
var direction = node.getSorter().getChildDirection(me._treeSet, child);
|
||||
|
||||
if ((direction > 0 && childFreeDisplacement.x < 0) || (direction < 0 && childFreeDisplacement.x > 0)) {
|
||||
child.resetFreeDisplacement();
|
||||
child.setFreeDisplacement({x:-childFreeDisplacement.x, y:childFreeDisplacement.y});
|
||||
}
|
||||
|
||||
offset.x += child.getFreeDisplacement().x;
|
||||
offset.y += child.getFreeDisplacement().y;
|
||||
|
||||
var parentX = parentPosition.x;
|
||||
var parentY = parentPosition.y;
|
||||
|
||||
var newPos = {x:parentX + offset.x, y:parentY + offset.y + me._calculateAlignOffset(node, child, heightById)};
|
||||
me._treeSet.updateBranchPosition(child, newPos);
|
||||
});
|
||||
|
||||
node._branchHeight = newBranchHeight;
|
||||
}
|
||||
|
||||
// Continue reordering the children nodes ...
|
||||
_.each(children, function (child) {
|
||||
this._layoutChildren(child, heightById);
|
||||
}, this);
|
||||
},
|
||||
|
||||
_calculateAlignOffset:function (node, child, heightById) {
|
||||
if (child.isFree()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var offset = 0;
|
||||
|
||||
var nodeHeight = node.getSize().height;
|
||||
var childHeight = child.getSize().height;
|
||||
|
||||
if (this._treeSet.isStartOfSubBranch(child) && this._branchIsTaller(child, heightById)) {
|
||||
if (this._treeSet.hasSinglePathToSingleLeaf(child)) {
|
||||
offset = heightById[child.getId()] / 2 - (childHeight + child.getSorter()._getVerticalPadding() * 2) / 2;
|
||||
} else {
|
||||
offset = this._treeSet.isLeaf(child) ? 0 : -(childHeight - nodeHeight) / 2;
|
||||
}
|
||||
} else if (nodeHeight > childHeight) {
|
||||
if (this._treeSet.getSiblings(child).length > 0) {
|
||||
offset = 0;
|
||||
} else {
|
||||
offset = nodeHeight / 2 - childHeight / 2;
|
||||
}
|
||||
}
|
||||
else if (childHeight > nodeHeight) {
|
||||
if (this._treeSet.getSiblings(child).length > 0) {
|
||||
offset = 0;
|
||||
} else {
|
||||
offset = -(childHeight / 2 - nodeHeight / 2);
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
},
|
||||
|
||||
_branchIsTaller:function (node, heightById) {
|
||||
return heightById[node.getId()] > (node.getSize().height + node.getSorter()._getVerticalPadding() * 2);
|
||||
},
|
||||
|
||||
_fixOverlapping:function (node, heightById) {
|
||||
var children = this._treeSet.getChildren(node);
|
||||
|
||||
if (node.isFree()) {
|
||||
this._shiftBranches(node, heightById);
|
||||
}
|
||||
|
||||
_.each(children, function (child) {
|
||||
this._fixOverlapping(child, heightById);
|
||||
}, this);
|
||||
},
|
||||
|
||||
_shiftBranches:function (node, heightById) {
|
||||
var shiftedBranches = [node];
|
||||
|
||||
var siblingsToShift = this._treeSet.getSiblingsInVerticalDirection(node, node.getFreeDisplacement().y);
|
||||
var last = node;
|
||||
_.each(siblingsToShift, function (sibling) {
|
||||
var overlappingOccurs = shiftedBranches.some(function (shiftedBranch) {
|
||||
return this._branchesOverlap(shiftedBranch, sibling, heightById);
|
||||
}, this);
|
||||
|
||||
if (!sibling.isFree() || overlappingOccurs) {
|
||||
var sAmount = node.getFreeDisplacement().y;
|
||||
this._treeSet.shiftBranchPosition(sibling, 0, sAmount);
|
||||
shiftedBranches.push(sibling);
|
||||
}
|
||||
}, this);
|
||||
|
||||
var branchesToShift = this._treeSet.getBranchesInVerticalDirection(node, node.getFreeDisplacement().y).filter(function (branch) {
|
||||
return !shiftedBranches.contains(branch);
|
||||
});
|
||||
|
||||
_.each(branchesToShift, function (branch) {
|
||||
var bAmount = node.getFreeDisplacement().y;
|
||||
this._treeSet.shiftBranchPosition(branch, 0, bAmount);
|
||||
shiftedBranches.push(branch);
|
||||
last = branch;
|
||||
}, this);
|
||||
},
|
||||
|
||||
_branchesOverlap:function (branchA, branchB, heightById) {
|
||||
// a branch doesn't really overlap with itself
|
||||
if (branchA == branchB) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var topA = branchA.getPosition().y - heightById[branchA.getId()] / 2;
|
||||
var bottomA = branchA.getPosition().y + heightById[branchA.getId()] / 2;
|
||||
var topB = branchB.getPosition().y - heightById[branchB.getId()] / 2;
|
||||
var bottomB = branchB.getPosition().y + heightById[branchB.getId()] / 2;
|
||||
|
||||
return !(topA >= bottomB || bottomA <= topB);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* @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();
|
||||
|
||||
|
||||
|
@ -1,395 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.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;
|
||||
},
|
||||
|
||||
_decodate:function (node) {
|
||||
node._children = [];
|
||||
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());
|
||||
$assert(!node._children, 'node already added');
|
||||
this._rootNodes.push(this._decodate(node));
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @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');
|
||||
|
||||
var parent = this.find(parentId);
|
||||
var child = this.find(childId, true);
|
||||
$assert(!child._parent, 'node already connected. Id:' + child.getId() + ",previous:" + child._parent);
|
||||
|
||||
parent._children.push(child);
|
||||
child._parent = parent;
|
||||
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);
|
||||
$assert(node._parent, "Node is not connected");
|
||||
|
||||
node._parent._children.erase(node);
|
||||
this._rootNodes.push(node);
|
||||
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');
|
||||
|
||||
var graphs = this._rootNodes;
|
||||
var result = null;
|
||||
for (var i = 0; i < graphs.length; i++) {
|
||||
var node = graphs[i];
|
||||
result = this._find(id, node);
|
||||
if (result) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
validate = !$defined(validate) ? true : validate;
|
||||
$assert(validate ? result : true, 'node could not be found id:' + id + "\n,RootedTreeSet" + this.dump());
|
||||
return result;
|
||||
|
||||
},
|
||||
|
||||
_find:function (id, parent) {
|
||||
if (parent.getId() == id) {
|
||||
return parent;
|
||||
|
||||
}
|
||||
|
||||
var result = null;
|
||||
var children = parent._children;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
result = this._find(id, child);
|
||||
if (result)
|
||||
break;
|
||||
}
|
||||
|
||||
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);
|
||||
if ($defined(parent)) {
|
||||
return this.getRootNode(parent);
|
||||
}
|
||||
|
||||
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), []);
|
||||
},
|
||||
|
||||
_getAncestors:function (node, ancestors) {
|
||||
var result = ancestors;
|
||||
if (node) {
|
||||
result.push(node);
|
||||
this._getAncestors(this.getParent(node), result);
|
||||
}
|
||||
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)) {
|
||||
return [];
|
||||
}
|
||||
var siblings = node._parent._children.filter(function (child) {
|
||||
return child != node;
|
||||
});
|
||||
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);
|
||||
},
|
||||
|
||||
_hasSinglePathToSingleLeaf:function (node) {
|
||||
var children = this.getChildren(node);
|
||||
|
||||
if (children.length == 1) {
|
||||
return this._hasSinglePathToSingleLeaf(children[0]);
|
||||
}
|
||||
|
||||
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 = "";
|
||||
for (var i = 0; i < branches.length; i++) {
|
||||
var branch = branches[i];
|
||||
result += this._dump(branch, "");
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
_dump:function (node, indent) {
|
||||
var result = indent + node + "\n";
|
||||
var children = this.getChildren(node);
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
result += this._dump(child, indent + " ");
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param canvas
|
||||
*/
|
||||
plot:function (canvas) {
|
||||
var branches = this._rootNodes;
|
||||
for (var i = 0; i < branches.length; i++) {
|
||||
var branch = branches[i];
|
||||
this._plot(canvas, branch);
|
||||
}
|
||||
},
|
||||
|
||||
_plot:function (canvas, node, root) {
|
||||
var children = this.getChildren(node);
|
||||
var cx = node.getPosition().x + canvas.width / 2 - node.getSize().width / 2;
|
||||
var cy = node.getPosition().y + canvas.height / 2 - node.getSize().height / 2;
|
||||
var rect = canvas.rect(cx, cy, node.getSize().width, node.getSize().height);
|
||||
var order = node.getOrder() == null ? "r" : node.getOrder();
|
||||
var text = canvas.text(node.getPosition().x + canvas.width / 2, node.getPosition().y + canvas.height / 2, node.getId() + "[" + order + "]");
|
||||
text.attr('fill', '#FFF');
|
||||
var fillColor = this._rootNodes.contains(node) ? "#000" : (node.isFree() ? "#abc" : "#c00");
|
||||
rect.attr('fill', fillColor);
|
||||
|
||||
var rectPosition = {x:rect.attr("x") - canvas.width / 2 + rect.attr("width") / 2, y:rect.attr("y") - canvas.height / 2 + rect.attr("height") / 2};
|
||||
var rectSize = {width:rect.attr("width"), height:rect.attr("height")};
|
||||
rect.click(function () {
|
||||
console.log("[id:" + node.getId() + ", order:" + node.getOrder() + ", position:(" + rectPosition.x + "," + rectPosition.y + "), size:" + rectSize.width + "x" + rectSize.height + ", freeDisplacement:(" + node.getFreeDisplacement().x + "," + node.getFreeDisplacement().y + ")]");
|
||||
});
|
||||
text.click(function () {
|
||||
console.log("[id:" + node.getId() + ", order:" + node.getOrder() + ", position:(" + rectPosition.x + "," + rectPosition.y + "), size:" + rectSize.width + "x" + rectSize.height + ", freeDisplacement:(" + node.getFreeDisplacement().x + "," + node.getFreeDisplacement().y + ")]");
|
||||
});
|
||||
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
this._plot(canvas, child);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @param position
|
||||
*/
|
||||
updateBranchPosition:function (node, position) {
|
||||
|
||||
var oldPos = node.getPosition();
|
||||
node.setPosition(position);
|
||||
|
||||
var xOffset = oldPos.x - position.x;
|
||||
var yOffset = oldPos.y - position.y;
|
||||
|
||||
var children = this.getChildren(node);
|
||||
var me = this;
|
||||
_.each(children, function (child) {
|
||||
me.shiftBranchPosition(child, xOffset, yOffset);
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* @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});
|
||||
|
||||
var children = this.getChildren(node);
|
||||
var me = this;
|
||||
_.each(children, function (child) {
|
||||
me.shiftBranchPosition(child, xOffset, yOffset);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* @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);
|
||||
var siblings = this.getSiblings(node).filter(function (sibling) {
|
||||
var sameSide = node.getPosition().x > parent.getPosition().x ? sibling.getPosition().x > parent.getPosition().x : sibling.getPosition().x < parent.getPosition().x;
|
||||
var orderOK = yOffset < 0 ? sibling.getOrder() < node.getOrder() : sibling.getOrder() > node.getOrder();
|
||||
return orderOK && sameSide;
|
||||
});
|
||||
|
||||
if (yOffset < 0) {
|
||||
siblings.reverse();
|
||||
}
|
||||
|
||||
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
|
||||
var rootNode = this.getRootNode(node);
|
||||
var branches = this.getChildren(rootNode).filter(function (child) {
|
||||
return this._find(node.getId(), child);
|
||||
}, this);
|
||||
|
||||
var branch = branches[0];
|
||||
var rootDescendants = this.getSiblings(branch).filter(function (sibling) {
|
||||
var sameSide = node.getPosition().x > rootNode.getPosition().x ? sibling.getPosition().x > rootNode.getPosition().x : sibling.getPosition().x < rootNode.getPosition().x;
|
||||
var sameDirection = yOffset < 0 ? sibling.getOrder() < branch.getOrder() : sibling.getOrder() > branch.getOrder();
|
||||
return sameSide && sameDirection;
|
||||
}, this);
|
||||
|
||||
return rootDescendants;
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -1,282 +0,0 @@
|
||||
/*
|
||||
* Copyright [2015] [wisemapping]
|
||||
*
|
||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
mindplot.layout.SymmetricSorter = new Class(/** @lends SymmetricSorter */{
|
||||
Extends:mindplot.layout.AbstractBasicSorter,
|
||||
/**
|
||||
* @constructs
|
||||
* @extends mindplot.layout.AbstractBasicSorter
|
||||
*/
|
||||
initialize:function () {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Predict the order and position of a dragged node.
|
||||
*
|
||||
* @param graph The tree set
|
||||
* @param parent The parent of the node
|
||||
* @param node The node
|
||||
* @param position The position of the drag
|
||||
* @param free Free drag or not
|
||||
* @return {*}
|
||||
*/
|
||||
predict:function (graph, parent, node, position, free) {
|
||||
|
||||
var self = this;
|
||||
var rootNode = graph.getRootNode(parent);
|
||||
|
||||
// If its a free node...
|
||||
if (free) {
|
||||
$assert($defined(position), "position cannot be null for predict in free positioning");
|
||||
$assert($defined(node), "node cannot be null for predict in free positioning");
|
||||
|
||||
var direction = this._getRelativeDirection(rootNode.getPosition(), parent.getPosition());
|
||||
var limitXPos = parent.getPosition().x + direction * (parent.getSize().width / 2 + node.getSize().width / 2 + mindplot.layout.SymmetricSorter.INTERNODE_HORIZONTAL_PADDING);
|
||||
|
||||
var xPos = direction > 0 ?
|
||||
(position.x >= limitXPos ? position.x : limitXPos) :
|
||||
(position.x <= limitXPos ? position.x : limitXPos);
|
||||
|
||||
return [0, {x:xPos, y:position.y}];
|
||||
}
|
||||
|
||||
// Its not a dragged node (it is being added)
|
||||
if (!node) {
|
||||
var parentDirection = self._getRelativeDirection(rootNode.getPosition(), parent.getPosition());
|
||||
var position = {
|
||||
x:parent.getPosition().x + parentDirection * (parent.getSize().width + mindplot.layout.SymmetricSorter.INTERNODE_HORIZONTAL_PADDING),
|
||||
y:parent.getPosition().y
|
||||
};
|
||||
return [graph.getChildren(parent).length, position];
|
||||
}
|
||||
|
||||
// If it is a dragged node...
|
||||
$assert($defined(position), "position cannot be null for predict in dragging");
|
||||
var nodeDirection = this._getRelativeDirection(rootNode.getPosition(), node.getPosition());
|
||||
var positionDirection = this._getRelativeDirection(rootNode.getPosition(), position);
|
||||
var siblings = graph.getSiblings(node);
|
||||
|
||||
// node has no siblings and its trying to reconnect to its own parent
|
||||
var sameParent = parent == graph.getParent(node);
|
||||
if (siblings.length == 0 && nodeDirection == positionDirection && sameParent) {
|
||||
return [node.getOrder(), node.getPosition()];
|
||||
}
|
||||
|
||||
var parentChildren = graph.getChildren(parent);
|
||||
|
||||
if (parentChildren.length == 0) {
|
||||
// Fit as a child of the parent node...
|
||||
var position = {
|
||||
x:parent.getPosition().x + positionDirection * (parent.getSize().width + mindplot.layout.SymmetricSorter.INTERNODE_HORIZONTAL_PADDING),
|
||||
y:parent.getPosition().y
|
||||
};
|
||||
return [0, position];
|
||||
} else {
|
||||
// Try to fit within ...
|
||||
var result = null;
|
||||
var last = parentChildren.getLast();
|
||||
for (var i = 0; i < parentChildren.length; i++) {
|
||||
var parentChild = parentChildren[i];
|
||||
var nodeAfter = (i + 1) == parentChild.length ? null : parentChildren[i + 1];
|
||||
|
||||
// Fit at the bottom
|
||||
if (!nodeAfter && position.y > parentChild.getPosition().y) {
|
||||
var order = (graph.getParent(node) && graph.getParent(node).getId() == parent.getId()) ?
|
||||
last.getOrder() : last.getOrder() + 1;
|
||||
var position = {
|
||||
x:parentChild.getPosition().x,
|
||||
y:parentChild.getPosition().y + parentChild.getSize().height + mindplot.layout.SymmetricSorter.INTERNODE_VERTICAL_PADDING * 2
|
||||
};
|
||||
return [order, position];
|
||||
}
|
||||
|
||||
// Fit after this node
|
||||
if (nodeAfter && position.y > parentChild.getPosition().y && position.y < nodeAfter.getPosition().y) {
|
||||
if (nodeAfter.getId() == node.getId() || parentChild.getId() == node.getId()) {
|
||||
return [node.getOrder(), node.getPosition()];
|
||||
} else {
|
||||
var order = position.y > node.getPosition().y ?
|
||||
nodeAfter.getOrder() - 1 : parentChild.getOrder() + 1;
|
||||
var position = {
|
||||
x:parentChild.getPosition().x,
|
||||
y:parentChild.getPosition().y + (nodeAfter.getPosition().y - parentChild.getPosition().y) / 2
|
||||
};
|
||||
|
||||
return [order, position];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Position wasn't below any node, so it must be fitted above the first
|
||||
var first = parentChildren[0];
|
||||
var position = {
|
||||
x:first.getPosition().x,
|
||||
y:first.getPosition().y - first.getSize().height - mindplot.layout.SymmetricSorter.INTERNODE_VERTICAL_PADDING * 2
|
||||
};
|
||||
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);
|
||||
|
||||
// Shift all the elements in one .
|
||||
for (var i = order; i < children.length; i++) {
|
||||
var node = children[i];
|
||||
node.setOrder(i + 1);
|
||||
}
|
||||
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);
|
||||
var order = node.getOrder();
|
||||
$assert(children[order] === node, "Node seems not to be in the right position");
|
||||
|
||||
// Shift all the nodes ...
|
||||
for (var i = node.getOrder() + 1; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
child.setOrder(child.getOrder() - 1);
|
||||
}
|
||||
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.");
|
||||
|
||||
var children = this._getSortedChildren(treeSet, node);
|
||||
|
||||
// Compute heights ...
|
||||
var heights = children.map(
|
||||
function (child) {
|
||||
return {id:child.getId(), order:child.getOrder(), position:child.getPosition(), width:child.getSize().width, height:this._computeChildrenHeight(treeSet, child)};
|
||||
}, this).reverse();
|
||||
|
||||
// Compute the center of the branch ...
|
||||
var totalHeight = 0;
|
||||
_.each(heights, function (elem) {
|
||||
totalHeight += elem.height;
|
||||
});
|
||||
var ysum = totalHeight / 2;
|
||||
|
||||
// Calculate the offsets ...
|
||||
var result = {};
|
||||
for (var i = 0; i < heights.length; i++) {
|
||||
ysum = ysum - heights[i].height;
|
||||
var childNode = treeSet.find(heights[i].id);
|
||||
var direction = this.getChildDirection(treeSet, childNode);
|
||||
|
||||
var yOffset = ysum + heights[i].height / 2;
|
||||
var xOffset = direction * (heights[i].width / 2 + node.getSize().width / 2 + mindplot.layout.SymmetricSorter.INTERNODE_HORIZONTAL_PADDING);
|
||||
|
||||
$assert(!isNaN(xOffset), "xOffset can not be null");
|
||||
$assert(!isNaN(yOffset), "yOffset can not be null");
|
||||
|
||||
result[heights[i].id] = {x:xOffset, y:yOffset};
|
||||
}
|
||||
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);
|
||||
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
$assert(children[i].getOrder() == i, "missing order elements");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @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");
|
||||
|
||||
var result;
|
||||
var rootNode = treeSet.getRootNode(child);
|
||||
if (treeSet.getParent(child) == rootNode) {
|
||||
// This is the case of a isolated child ... In this case, the directions is based on the root.
|
||||
result = Math.sign(rootNode.getPosition().x);
|
||||
} else {
|
||||
// if this is not the case, honor the direction of the parent ...
|
||||
var parent = treeSet.getParent(child);
|
||||
var grandParent = treeSet.getParent(parent);
|
||||
var sorter = grandParent.getSorter();
|
||||
result = sorter.getChildDirection(treeSet, parent);
|
||||
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
/** @return {String} the print name of this class */
|
||||
toString:function () {
|
||||
return "Symmetric Sorter";
|
||||
},
|
||||
|
||||
_getVerticalPadding:function () {
|
||||
return mindplot.layout.SymmetricSorter.INTERNODE_VERTICAL_PADDING;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @constant
|
||||
* @type {Number}
|
||||
* @default
|
||||
*/
|
||||
mindplot.layout.SymmetricSorter.INTERNODE_VERTICAL_PADDING = 5;
|
||||
/**
|
||||
* @constant
|
||||
* @type {Number}
|
||||
* @default
|
||||
*/
|
||||
mindplot.layout.SymmetricSorter.INTERNODE_HORIZONTAL_PADDING = 30;
|
||||
|
||||
|
@ -1,49 +0,0 @@
|
||||
BootstrapDialog.Request = new Class({
|
||||
|
||||
Extends: BootstrapDialog,
|
||||
|
||||
initialize: function(url, title, options) {
|
||||
this.parent(title, options);
|
||||
this.requestOptions = {};
|
||||
this.requestOptions.cache = false;
|
||||
var me = this;
|
||||
this.requestOptions.fail = function(xhr) {
|
||||
// Intercept form requests ...
|
||||
console.log("Failure:");
|
||||
console.log(xhr);
|
||||
};
|
||||
|
||||
this.requestOptions.success = function() {
|
||||
// Intercept form requests ...
|
||||
var forms = me._native.find('form');
|
||||
_.each(forms, function(form) {
|
||||
$(form).on('submit', function(event) {
|
||||
// Intercept form ...
|
||||
me.requestOptions.url = form.action;
|
||||
me.requestOptions.method = form.method ? form.method : 'post';
|
||||
$.ajax(me.requestOptions);
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
this._native.find('.modal-body').load(url, function () {
|
||||
me.acceptButton.unbind('click').click(function () {
|
||||
submitDialogForm();
|
||||
});
|
||||
me._native.on('hidden.bs.modal', function () {
|
||||
$(this).remove();
|
||||
});
|
||||
me.show();
|
||||
});
|
||||
},
|
||||
|
||||
onDialogShown: function() {
|
||||
if (typeof(onDialogShown) == "function") {
|
||||
onDialogShown();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
});
|
@ -1,111 +0,0 @@
|
||||
var BootstrapDialog = new Class({
|
||||
Implements: Options,
|
||||
|
||||
options: {
|
||||
cancelButton: false,
|
||||
closeButton: false,
|
||||
acceptButton: true,
|
||||
removeButton:false,
|
||||
errorMessage: false,
|
||||
onEventData:{}
|
||||
},
|
||||
|
||||
initialize: function (title, options) {
|
||||
this.setOptions(options);
|
||||
this.options.onEventData.dialog = this;
|
||||
this._native = $('<div class="modal fade" tabindex="-1"></div>').append('<div class="modal-dialog"></div>');
|
||||
var content = $('<div class="modal-content"></div>');
|
||||
var header = this._buildHeader(title);
|
||||
if (header) {
|
||||
content.append(header);
|
||||
}
|
||||
var body = $('<div class="modal-body"></div>');
|
||||
if(this.options.errorMessage){
|
||||
var error = $('<div class="alert alert-danger"></div>');
|
||||
error.hide();
|
||||
body.append(error);
|
||||
}
|
||||
content.append(body);
|
||||
var footer = this._buildFooter();
|
||||
if (footer) {
|
||||
content.append(footer);
|
||||
}
|
||||
this._native.find(".modal-dialog").append(content);
|
||||
this._native.on('hidden.bs.modal', function() {
|
||||
$(this).remove();
|
||||
});
|
||||
this._native.on('shown.bs.modal', this.onDialogShown);
|
||||
},
|
||||
|
||||
_buildFooter: function() {
|
||||
var footer = null;
|
||||
if (this.options.acceptButton || this.options.removeButton || this.options.cancelButton) {
|
||||
footer = $('<div class="modal-footer" style="paddingTop:5;textAlign:center">');
|
||||
}
|
||||
if (this.options.acceptButton) {
|
||||
this.acceptButton = $('<button type="button" class="btn btn-primary" id="acceptBtn" data-dismiss="modal">'+ $msg('ACCEPT') + '</button>');
|
||||
footer.append(this.acceptButton);
|
||||
this.acceptButton.unbind('click').on("click",this.options.onEventData, this.onAcceptClick)
|
||||
}
|
||||
if (this.options.removeButton) {
|
||||
this.removeButton = $('<button type="button" class="btn btn-secondary" id="removeBtn" data-dismiss="modal">'+ $msg('REMOVE') +'</button>');
|
||||
footer.append(this.removeButton);
|
||||
this.removeButton.on('click', this.options.onEventData, this.onRemoveClick);
|
||||
}
|
||||
if (this.options.cancelButton) {
|
||||
footer.append('<button type="button" class="btn btn-secondary" data-dismiss="modal">'+ $msg('CANCEL') +'</button>');
|
||||
}
|
||||
return footer;
|
||||
},
|
||||
|
||||
_buildHeader: function(title) {
|
||||
var header = null;
|
||||
if (this.options.closeButton || title) {
|
||||
header = $('<div class="modal-header"></div>');
|
||||
}
|
||||
if (this.options.closeButton) {
|
||||
header.append(
|
||||
'<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>'
|
||||
);
|
||||
}
|
||||
if (title) {
|
||||
header.append('<h2 class="modal-title">' + title + '</h2>');
|
||||
}
|
||||
return header;
|
||||
},
|
||||
|
||||
onAcceptClick: function(event) {
|
||||
throw "Unsupported operation";
|
||||
},
|
||||
|
||||
onDialogShown: function() {},
|
||||
onRemoveClick: function(event) {
|
||||
throw "Unsupported operation";
|
||||
},
|
||||
|
||||
show: function () {
|
||||
this._native.modal();
|
||||
},
|
||||
|
||||
setContent: function(content) {
|
||||
var modalBody = this._native.find('.modal-body');
|
||||
modalBody.append(content);
|
||||
},
|
||||
|
||||
css: function(options){
|
||||
this._native.find('.modal-dialog').css(options);
|
||||
},
|
||||
|
||||
close: function() {
|
||||
this._native.modal('hide');
|
||||
},
|
||||
|
||||
alertError: function(message){
|
||||
this._native.find('.alert-danger').text(message);
|
||||
this._native.find('.alert-danger').show();
|
||||
},
|
||||
|
||||
cleanError: function(){
|
||||
this._native.find('.alert-danger').hide();
|
||||
}
|
||||
});
|
@ -1,951 +0,0 @@
|
||||
/*!
|
||||
* Bootstrap Colorpicker
|
||||
* http://mjolnic.github.io/bootstrap-colorpicker/
|
||||
*
|
||||
* Originally written by (c) 2012 Stefan Petre
|
||||
* Licensed under the Apache License v2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||
*
|
||||
* @todo Update DOCS
|
||||
*/
|
||||
(function($) {
|
||||
'use strict';
|
||||
|
||||
// Color object
|
||||
var Color = function(val) {
|
||||
this.value = {
|
||||
h: 0,
|
||||
s: 0,
|
||||
b: 0,
|
||||
a: 1
|
||||
};
|
||||
this.origFormat = null; // original string format
|
||||
if (val) {
|
||||
if (val.toLowerCase !== undefined) {
|
||||
this.setColor(val);
|
||||
} else if (val.h !== undefined) {
|
||||
this.value = val;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Color.prototype = {
|
||||
constructor: Color,
|
||||
_sanitizeNumber: function(val) {
|
||||
if (typeof val === 'number') {
|
||||
return val;
|
||||
}
|
||||
if (isNaN(val) || (val === null) || (val === '') || (val === undefined)) {
|
||||
return 1;
|
||||
}
|
||||
if (val.toLowerCase !== undefined) {
|
||||
return parseFloat(val);
|
||||
}
|
||||
return 1;
|
||||
},
|
||||
//parse a string to HSB
|
||||
setColor: function(strVal) {
|
||||
strVal = strVal.toLowerCase();
|
||||
this.value = this.stringToHSB(strVal) || {
|
||||
h: 0,
|
||||
s: 0,
|
||||
b: 0,
|
||||
a: 1
|
||||
};
|
||||
},
|
||||
stringToHSB: function(strVal) {
|
||||
strVal = strVal.toLowerCase();
|
||||
var that = this,
|
||||
result = false;
|
||||
$.each(this.stringParsers, function(i, parser) {
|
||||
var match = parser.re.exec(strVal),
|
||||
values = match && parser.parse.apply(that, [match]),
|
||||
format = parser.format || 'rgba';
|
||||
if (values) {
|
||||
if (format.match(/hsla?/)) {
|
||||
result = that.RGBtoHSB.apply(that, that.HSLtoRGB.apply(that, values));
|
||||
} else {
|
||||
result = that.RGBtoHSB.apply(that, values);
|
||||
}
|
||||
that.origFormat = format;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return result;
|
||||
},
|
||||
setHue: function(h) {
|
||||
this.value.h = 1 - h;
|
||||
},
|
||||
setSaturation: function(s) {
|
||||
this.value.s = s;
|
||||
},
|
||||
setBrightness: function(b) {
|
||||
this.value.b = 1 - b;
|
||||
},
|
||||
setAlpha: function(a) {
|
||||
this.value.a = parseInt((1 - a) * 100, 10) / 100;
|
||||
},
|
||||
toRGB: function(h, s, v, a) {
|
||||
h = h || this.value.h;
|
||||
s = s || this.value.s;
|
||||
v = v || this.value.b;
|
||||
a = a || this.value.a;
|
||||
|
||||
var r, g, b, i, f, p, q, t;
|
||||
if (h && s === undefined && v === undefined) {
|
||||
s = h.s, v = h.v, h = h.h;
|
||||
}
|
||||
i = Math.floor(h * 6);
|
||||
f = h * 6 - i;
|
||||
p = v * (1 - s);
|
||||
q = v * (1 - f * s);
|
||||
t = v * (1 - (1 - f) * s);
|
||||
switch (i % 6) {
|
||||
case 0:
|
||||
r = v, g = t, b = p;
|
||||
break;
|
||||
case 1:
|
||||
r = q, g = v, b = p;
|
||||
break;
|
||||
case 2:
|
||||
r = p, g = v, b = t;
|
||||
break;
|
||||
case 3:
|
||||
r = p, g = q, b = v;
|
||||
break;
|
||||
case 4:
|
||||
r = t, g = p, b = v;
|
||||
break;
|
||||
case 5:
|
||||
r = v, g = p, b = q;
|
||||
break;
|
||||
}
|
||||
return {
|
||||
r: Math.floor(r * 255),
|
||||
g: Math.floor(g * 255),
|
||||
b: Math.floor(b * 255),
|
||||
a: a
|
||||
};
|
||||
},
|
||||
toHex: function(h, s, b, a) {
|
||||
var rgb = this.toRGB(h, s, b, a);
|
||||
return '#' + ((1 << 24) | (parseInt(rgb.r) << 16) | (parseInt(rgb.g) << 8) | parseInt(rgb.b)).toString(16).substr(1);
|
||||
},
|
||||
toHSL: function(h, s, b, a) {
|
||||
h = h || this.value.h;
|
||||
s = s || this.value.s;
|
||||
b = b || this.value.b;
|
||||
a = a || this.value.a;
|
||||
|
||||
var H = h,
|
||||
L = (2 - s) * b,
|
||||
S = s * b;
|
||||
if (L > 0 && L <= 1) {
|
||||
S /= L;
|
||||
} else {
|
||||
S /= 2 - L;
|
||||
}
|
||||
L /= 2;
|
||||
if (S > 1) {
|
||||
S = 1;
|
||||
}
|
||||
return {
|
||||
h: isNaN(H) ? 0 : H,
|
||||
s: isNaN(S) ? 0 : S,
|
||||
l: isNaN(L) ? 0 : L,
|
||||
a: isNaN(a) ? 0 : a,
|
||||
};
|
||||
},
|
||||
RGBtoHSB: function(r, g, b, a) {
|
||||
r /= 255;
|
||||
g /= 255;
|
||||
b /= 255;
|
||||
|
||||
var H, S, V, C;
|
||||
V = Math.max(r, g, b);
|
||||
C = V - Math.min(r, g, b);
|
||||
H = (C === 0 ? null :
|
||||
V === r ? (g - b) / C :
|
||||
V === g ? (b - r) / C + 2 :
|
||||
(r - g) / C + 4
|
||||
);
|
||||
H = ((H + 360) % 6) * 60 / 360;
|
||||
S = C === 0 ? 0 : C / V;
|
||||
return {
|
||||
h: this._sanitizeNumber(H),
|
||||
s: S,
|
||||
b: V,
|
||||
a: this._sanitizeNumber(a)
|
||||
};
|
||||
},
|
||||
HueToRGB: function(p, q, h) {
|
||||
if (h < 0) {
|
||||
h += 1;
|
||||
} else if (h > 1) {
|
||||
h -= 1;
|
||||
}
|
||||
if ((h * 6) < 1) {
|
||||
return p + (q - p) * h * 6;
|
||||
} else if ((h * 2) < 1) {
|
||||
return q;
|
||||
} else if ((h * 3) < 2) {
|
||||
return p + (q - p) * ((2 / 3) - h) * 6;
|
||||
} else {
|
||||
return p;
|
||||
}
|
||||
},
|
||||
HSLtoRGB: function(h, s, l, a) {
|
||||
if (s < 0) {
|
||||
s = 0;
|
||||
}
|
||||
var q;
|
||||
if (l <= 0.5) {
|
||||
q = l * (1 + s);
|
||||
} else {
|
||||
q = l + s - (l * s);
|
||||
}
|
||||
|
||||
var p = 2 * l - q;
|
||||
|
||||
var tr = h + (1 / 3);
|
||||
var tg = h;
|
||||
var tb = h - (1 / 3);
|
||||
|
||||
var r = Math.round(this.HueToRGB(p, q, tr) * 255);
|
||||
var g = Math.round(this.HueToRGB(p, q, tg) * 255);
|
||||
var b = Math.round(this.HueToRGB(p, q, tb) * 255);
|
||||
return [r, g, b, this._sanitizeNumber(a)];
|
||||
},
|
||||
toString: function(format) {
|
||||
format = format || 'rgba';
|
||||
switch (format) {
|
||||
case 'rgb':
|
||||
{
|
||||
var rgb = this.toRGB();
|
||||
return 'rgb(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ')';
|
||||
}
|
||||
break;
|
||||
case 'rgba':
|
||||
{
|
||||
var rgb = this.toRGB();
|
||||
return 'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + rgb.a + ')';
|
||||
}
|
||||
break;
|
||||
case 'hsl':
|
||||
{
|
||||
var hsl = this.toHSL();
|
||||
return 'hsl(' + Math.round(hsl.h * 360) + ',' + Math.round(hsl.s * 100) + '%,' + Math.round(hsl.l * 100) + '%)';
|
||||
}
|
||||
break;
|
||||
case 'hsla':
|
||||
{
|
||||
var hsl = this.toHSL();
|
||||
return 'hsla(' + Math.round(hsl.h * 360) + ',' + Math.round(hsl.s * 100) + '%,' + Math.round(hsl.l * 100) + '%,' + hsl.a + ')';
|
||||
}
|
||||
break;
|
||||
case 'hex':
|
||||
{
|
||||
return this.toHex();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
// a set of RE's that can match strings and generate color tuples.
|
||||
// from John Resig color plugin
|
||||
// https://github.com/jquery/jquery-color/
|
||||
stringParsers: [{
|
||||
re: /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/,
|
||||
format: 'hex',
|
||||
parse: function(execResult) {
|
||||
return [
|
||||
parseInt(execResult[1], 16),
|
||||
parseInt(execResult[2], 16),
|
||||
parseInt(execResult[3], 16),
|
||||
1
|
||||
];
|
||||
}
|
||||
}, {
|
||||
re: /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/,
|
||||
format: 'hex',
|
||||
parse: function(execResult) {
|
||||
return [
|
||||
parseInt(execResult[1] + execResult[1], 16),
|
||||
parseInt(execResult[2] + execResult[2], 16),
|
||||
parseInt(execResult[3] + execResult[3], 16),
|
||||
1
|
||||
];
|
||||
}
|
||||
}, {
|
||||
re: /rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*?\)/,
|
||||
format: 'rgb',
|
||||
parse: function(execResult) {
|
||||
return [
|
||||
execResult[1],
|
||||
execResult[2],
|
||||
execResult[3],
|
||||
1
|
||||
];
|
||||
}
|
||||
}, {
|
||||
re: /rgb\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*?\)/,
|
||||
format: 'rgb',
|
||||
parse: function(execResult) {
|
||||
return [
|
||||
2.55 * execResult[1],
|
||||
2.55 * execResult[2],
|
||||
2.55 * execResult[3],
|
||||
1
|
||||
];
|
||||
}
|
||||
}, {
|
||||
re: /rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
|
||||
format: 'rgba',
|
||||
parse: function(execResult) {
|
||||
return [
|
||||
execResult[1],
|
||||
execResult[2],
|
||||
execResult[3],
|
||||
execResult[4]
|
||||
];
|
||||
}
|
||||
}, {
|
||||
re: /rgba\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
|
||||
format: 'rgba',
|
||||
parse: function(execResult) {
|
||||
return [
|
||||
2.55 * execResult[1],
|
||||
2.55 * execResult[2],
|
||||
2.55 * execResult[3],
|
||||
execResult[4]
|
||||
];
|
||||
}
|
||||
}, {
|
||||
re: /hsl\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*?\)/,
|
||||
format: 'hsl',
|
||||
parse: function(execResult) {
|
||||
return [
|
||||
execResult[1] / 360,
|
||||
execResult[2] / 100,
|
||||
execResult[3] / 100,
|
||||
execResult[4]
|
||||
];
|
||||
}
|
||||
}, {
|
||||
re: /hsla\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
|
||||
format: 'hsla',
|
||||
parse: function(execResult) {
|
||||
return [
|
||||
execResult[1] / 360,
|
||||
execResult[2] / 100,
|
||||
execResult[3] / 100,
|
||||
execResult[4]
|
||||
];
|
||||
}
|
||||
}, {
|
||||
//predefined color name
|
||||
re: /^([a-z]{3,})$/,
|
||||
format: 'alias',
|
||||
parse: function(execResult) {
|
||||
var hexval = this.colorNameToHex(execResult[0]) || '#000000';
|
||||
var match = this.stringParsers[0].re.exec(hexval),
|
||||
values = match && this.stringParsers[0].parse.apply(this, [match]);
|
||||
return values;
|
||||
}
|
||||
}],
|
||||
colorNameToHex: function(name) {
|
||||
// 140 predefined colors from the HTML Colors spec
|
||||
var colors = {
|
||||
"aliceblue": "#f0f8ff",
|
||||
"antiquewhite": "#faebd7",
|
||||
"aqua": "#00ffff",
|
||||
"aquamarine": "#7fffd4",
|
||||
"azure": "#f0ffff",
|
||||
"beige": "#f5f5dc",
|
||||
"bisque": "#ffe4c4",
|
||||
"black": "#000000",
|
||||
"blanchedalmond": "#ffebcd",
|
||||
"blue": "#0000ff",
|
||||
"blueviolet": "#8a2be2",
|
||||
"brown": "#a52a2a",
|
||||
"burlywood": "#deb887",
|
||||
"cadetblue": "#5f9ea0",
|
||||
"chartreuse": "#7fff00",
|
||||
"chocolate": "#d2691e",
|
||||
"coral": "#ff7f50",
|
||||
"cornflowerblue": "#6495ed",
|
||||
"cornsilk": "#fff8dc",
|
||||
"crimson": "#dc143c",
|
||||
"cyan": "#00ffff",
|
||||
"darkblue": "#00008b",
|
||||
"darkcyan": "#008b8b",
|
||||
"darkgoldenrod": "#b8860b",
|
||||
"darkgray": "#a9a9a9",
|
||||
"darkgreen": "#006400",
|
||||
"darkkhaki": "#bdb76b",
|
||||
"darkmagenta": "#8b008b",
|
||||
"darkolivegreen": "#556b2f",
|
||||
"darkorange": "#ff8c00",
|
||||
"darkorchid": "#9932cc",
|
||||
"darkred": "#8b0000",
|
||||
"darksalmon": "#e9967a",
|
||||
"darkseagreen": "#8fbc8f",
|
||||
"darkslateblue": "#483d8b",
|
||||
"darkslategray": "#2f4f4f",
|
||||
"darkturquoise": "#00ced1",
|
||||
"darkviolet": "#9400d3",
|
||||
"deeppink": "#ff1493",
|
||||
"deepskyblue": "#00bfff",
|
||||
"dimgray": "#696969",
|
||||
"dodgerblue": "#1e90ff",
|
||||
"firebrick": "#b22222",
|
||||
"floralwhite": "#fffaf0",
|
||||
"forestgreen": "#228b22",
|
||||
"fuchsia": "#ff00ff",
|
||||
"gainsboro": "#dcdcdc",
|
||||
"ghostwhite": "#f8f8ff",
|
||||
"gold": "#ffd700",
|
||||
"goldenrod": "#daa520",
|
||||
"gray": "#808080",
|
||||
"green": "#008000",
|
||||
"greenyellow": "#adff2f",
|
||||
"honeydew": "#f0fff0",
|
||||
"hotpink": "#ff69b4",
|
||||
"indianred ": "#cd5c5c",
|
||||
"indigo ": "#4b0082",
|
||||
"ivory": "#fffff0",
|
||||
"khaki": "#f0e68c",
|
||||
"lavender": "#e6e6fa",
|
||||
"lavenderblush": "#fff0f5",
|
||||
"lawngreen": "#7cfc00",
|
||||
"lemonchiffon": "#fffacd",
|
||||
"lightblue": "#add8e6",
|
||||
"lightcoral": "#f08080",
|
||||
"lightcyan": "#e0ffff",
|
||||
"lightgoldenrodyellow": "#fafad2",
|
||||
"lightgrey": "#d3d3d3",
|
||||
"lightgreen": "#90ee90",
|
||||
"lightpink": "#ffb6c1",
|
||||
"lightsalmon": "#ffa07a",
|
||||
"lightseagreen": "#20b2aa",
|
||||
"lightskyblue": "#87cefa",
|
||||
"lightslategray": "#778899",
|
||||
"lightsteelblue": "#b0c4de",
|
||||
"lightyellow": "#ffffe0",
|
||||
"lime": "#00ff00",
|
||||
"limegreen": "#32cd32",
|
||||
"linen": "#faf0e6",
|
||||
"magenta": "#ff00ff",
|
||||
"maroon": "#800000",
|
||||
"mediumaquamarine": "#66cdaa",
|
||||
"mediumblue": "#0000cd",
|
||||
"mediumorchid": "#ba55d3",
|
||||
"mediumpurple": "#9370d8",
|
||||
"mediumseagreen": "#3cb371",
|
||||
"mediumslateblue": "#7b68ee",
|
||||
"mediumspringgreen": "#00fa9a",
|
||||
"mediumturquoise": "#48d1cc",
|
||||
"mediumvioletred": "#c71585",
|
||||
"midnightblue": "#191970",
|
||||
"mintcream": "#f5fffa",
|
||||
"mistyrose": "#ffe4e1",
|
||||
"moccasin": "#ffe4b5",
|
||||
"navajowhite": "#ffdead",
|
||||
"navy": "#000080",
|
||||
"oldlace": "#fdf5e6",
|
||||
"olive": "#808000",
|
||||
"olivedrab": "#6b8e23",
|
||||
"orange": "#ffa500",
|
||||
"orangered": "#ff4500",
|
||||
"orchid": "#da70d6",
|
||||
"palegoldenrod": "#eee8aa",
|
||||
"palegreen": "#98fb98",
|
||||
"paleturquoise": "#afeeee",
|
||||
"palevioletred": "#d87093",
|
||||
"papayawhip": "#ffefd5",
|
||||
"peachpuff": "#ffdab9",
|
||||
"peru": "#cd853f",
|
||||
"pink": "#ffc0cb",
|
||||
"plum": "#dda0dd",
|
||||
"powderblue": "#b0e0e6",
|
||||
"purple": "#800080",
|
||||
"red": "#ff0000",
|
||||
"rosybrown": "#bc8f8f",
|
||||
"royalblue": "#4169e1",
|
||||
"saddlebrown": "#8b4513",
|
||||
"salmon": "#fa8072",
|
||||
"sandybrown": "#f4a460",
|
||||
"seagreen": "#2e8b57",
|
||||
"seashell": "#fff5ee",
|
||||
"sienna": "#a0522d",
|
||||
"silver": "#c0c0c0",
|
||||
"skyblue": "#87ceeb",
|
||||
"slateblue": "#6a5acd",
|
||||
"slategray": "#708090",
|
||||
"snow": "#fffafa",
|
||||
"springgreen": "#00ff7f",
|
||||
"steelblue": "#4682b4",
|
||||
"tan": "#d2b48c",
|
||||
"teal": "#008080",
|
||||
"thistle": "#d8bfd8",
|
||||
"tomato": "#ff6347",
|
||||
"turquoise": "#40e0d0",
|
||||
"violet": "#ee82ee",
|
||||
"wheat": "#f5deb3",
|
||||
"white": "#ffffff",
|
||||
"whitesmoke": "#f5f5f5",
|
||||
"yellow": "#ffff00",
|
||||
"yellowgreen": "#9acd32"
|
||||
};
|
||||
|
||||
if (typeof colors[name.toLowerCase()] !== 'undefined') {
|
||||
return colors[name.toLowerCase()];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var defaults = {
|
||||
horizontal: false, // horizontal mode layout ?
|
||||
inline: false, //forces to show the colorpicker as an inline element
|
||||
color: false, //forces a color
|
||||
format: false, //forces a format
|
||||
input: 'input', // children input selector
|
||||
container: false, // container selector
|
||||
component: '.add-on, .input-group-addon', // children component selector
|
||||
sliders: {
|
||||
saturation: {
|
||||
maxLeft: 100,
|
||||
maxTop: 100,
|
||||
callLeft: 'setSaturation',
|
||||
callTop: 'setBrightness'
|
||||
},
|
||||
hue: {
|
||||
maxLeft: 0,
|
||||
maxTop: 100,
|
||||
callLeft: false,
|
||||
callTop: 'setHue'
|
||||
},
|
||||
alpha: {
|
||||
maxLeft: 0,
|
||||
maxTop: 100,
|
||||
callLeft: false,
|
||||
callTop: 'setAlpha'
|
||||
}
|
||||
},
|
||||
slidersHorz: {
|
||||
saturation: {
|
||||
maxLeft: 100,
|
||||
maxTop: 100,
|
||||
callLeft: 'setSaturation',
|
||||
callTop: 'setBrightness'
|
||||
},
|
||||
hue: {
|
||||
maxLeft: 100,
|
||||
maxTop: 0,
|
||||
callLeft: 'setHue',
|
||||
callTop: false
|
||||
},
|
||||
alpha: {
|
||||
maxLeft: 100,
|
||||
maxTop: 0,
|
||||
callLeft: 'setAlpha',
|
||||
callTop: false
|
||||
}
|
||||
},
|
||||
template: '<div class="colorpicker dropdown-menu">' +
|
||||
'<div class="colorpicker-saturation"><i><b></b></i></div>' +
|
||||
'<div class="colorpicker-hue"><i></i></div>' +
|
||||
'<div class="colorpicker-alpha"><i></i></div>' +
|
||||
'<div class="colorpicker-color"><div /></div>' +
|
||||
'</div>'
|
||||
};
|
||||
|
||||
var Colorpicker = function(element, options) {
|
||||
this.element = $(element).addClass('colorpicker-element');
|
||||
this.options = $.extend({}, defaults, this.element.data(), options);
|
||||
this.component = this.options.component;
|
||||
this.component = (this.component !== false) ? this.element.find(this.component) : false;
|
||||
if (this.component && (this.component.length === 0)) {
|
||||
this.component = false;
|
||||
}
|
||||
this.container = (this.options.container === true) ? this.element : this.options.container;
|
||||
this.container = (this.container !== false) ? $(this.container) : false;
|
||||
|
||||
// Is the element an input? Should we search inside for any input?
|
||||
this.input = this.element.is('input') ? this.element : (this.options.input ?
|
||||
this.element.find(this.options.input) : false);
|
||||
if (this.input && (this.input.length === 0)) {
|
||||
this.input = false;
|
||||
}
|
||||
// Set HSB color
|
||||
this.color = new Color(this.options.color !== false ? this.options.color : this.getValue());
|
||||
this.format = this.options.format !== false ? this.options.format : this.color.origFormat;
|
||||
|
||||
// Setup picker
|
||||
this.picker = $(this.options.template);
|
||||
if (this.options.inline) {
|
||||
this.picker.addClass('colorpicker-inline colorpicker-visible');
|
||||
} else {
|
||||
this.picker.addClass('colorpicker-hidden');
|
||||
}
|
||||
if (this.options.horizontal) {
|
||||
this.picker.addClass('colorpicker-horizontal');
|
||||
}
|
||||
if (this.format === 'rgba' || this.format === 'hsla') {
|
||||
this.picker.addClass('colorpicker-with-alpha');
|
||||
}
|
||||
this.picker.on('mousedown.colorpicker', $.proxy(this.mousedown, this));
|
||||
this.picker.appendTo(this.container ? this.container : $('body'));
|
||||
|
||||
// Bind events
|
||||
if (this.input !== false) {
|
||||
this.input.on({
|
||||
'keyup.colorpicker': $.proxy(this.keyup, this)
|
||||
});
|
||||
if (this.component === false) {
|
||||
this.element.on({
|
||||
'focus.colorpicker': $.proxy(this.show, this)
|
||||
});
|
||||
}
|
||||
if (this.options.inline === false) {
|
||||
this.element.on({
|
||||
'focusout.colorpicker': $.proxy(this.hide, this)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (this.component !== false) {
|
||||
this.component.on({
|
||||
'click.colorpicker': $.proxy(this.show, this)
|
||||
});
|
||||
}
|
||||
|
||||
if ((this.input === false) && (this.component === false)) {
|
||||
this.element.on({
|
||||
'click.colorpicker': $.proxy(this.show, this)
|
||||
});
|
||||
}
|
||||
this.update();
|
||||
|
||||
$($.proxy(function() {
|
||||
this.element.trigger('create');
|
||||
}, this));
|
||||
};
|
||||
|
||||
Colorpicker.version = '2.0.0-beta';
|
||||
|
||||
Colorpicker.Color = Color;
|
||||
|
||||
Colorpicker.prototype = {
|
||||
constructor: Colorpicker,
|
||||
destroy: function() {
|
||||
this.picker.remove();
|
||||
this.element.removeData('colorpicker').off('.colorpicker');
|
||||
if (this.input !== false) {
|
||||
this.input.off('.colorpicker');
|
||||
}
|
||||
if (this.component !== false) {
|
||||
this.component.off('.colorpicker');
|
||||
}
|
||||
this.element.removeClass('colorpicker-element');
|
||||
this.element.trigger({
|
||||
type: 'destroy'
|
||||
});
|
||||
},
|
||||
reposition: function() {
|
||||
if (this.options.inline !== false) {
|
||||
return false;
|
||||
}
|
||||
var offset = this.component ? this.component.offset() : this.element.offset();
|
||||
this.picker.css({
|
||||
top: offset.top + (this.component ? this.component.outerHeight() : this.element.outerHeight()),
|
||||
left: offset.left
|
||||
});
|
||||
},
|
||||
show: function(e) {
|
||||
if (this.isDisabled()) {
|
||||
return false;
|
||||
}
|
||||
this.picker.addClass('colorpicker-visible').removeClass('colorpicker-hidden');
|
||||
this.reposition();
|
||||
$(window).on('resize.colorpicker', $.proxy(this.reposition, this));
|
||||
if (!this.hasInput() && e) {
|
||||
if (e.stopPropagation && e.preventDefault) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
if (this.options.inline === false) {
|
||||
$(window.document).on({
|
||||
'mousedown.colorpicker': $.proxy(this.hide, this)
|
||||
});
|
||||
}
|
||||
this.element.trigger({
|
||||
type: 'showPicker',
|
||||
color: this.color
|
||||
});
|
||||
},
|
||||
hide: function() {
|
||||
this.picker.addClass('colorpicker-hidden').removeClass('colorpicker-visible');
|
||||
$(window).off('resize.colorpicker', this.reposition);
|
||||
$(document).off({
|
||||
'mousedown.colorpicker': this.hide
|
||||
});
|
||||
this.update();
|
||||
this.element.trigger({
|
||||
type: 'hidePicker',
|
||||
color: this.color
|
||||
});
|
||||
},
|
||||
updateData: function(val) {
|
||||
val = val || this.color.toString(this.format);
|
||||
this.element.data('color', val);
|
||||
return val;
|
||||
},
|
||||
updateInput: function(val) {
|
||||
val = val || this.color.toString(this.format);
|
||||
if (this.input !== false) {
|
||||
this.input.prop('value', val);
|
||||
}
|
||||
return val;
|
||||
},
|
||||
updatePicker: function(val) {
|
||||
if (val !== undefined) {
|
||||
this.color = new Color(val);
|
||||
}
|
||||
var sl = (this.options.horizontal === false) ? this.options.sliders : this.options.slidersHorz;
|
||||
var icns = this.picker.find('i');
|
||||
if (icns.length === 0) {
|
||||
return;
|
||||
}
|
||||
if (this.options.horizontal === false) {
|
||||
sl = this.options.sliders;
|
||||
icns.eq(1).css('top', sl.hue.maxTop * (1 - this.color.value.h)).end()
|
||||
.eq(2).css('top', sl.alpha.maxTop * (1 - this.color.value.a));
|
||||
} else {
|
||||
sl = this.options.slidersHorz;
|
||||
icns.eq(1).css('left', sl.hue.maxLeft * (1 - this.color.value.h)).end()
|
||||
.eq(2).css('left', sl.alpha.maxLeft * (1 - this.color.value.a));
|
||||
}
|
||||
icns.eq(0).css({
|
||||
'top': sl.saturation.maxTop - this.color.value.b * sl.saturation.maxTop,
|
||||
'left': this.color.value.s * sl.saturation.maxLeft
|
||||
});
|
||||
this.picker.find('.colorpicker-saturation').css('backgroundColor', this.color.toHex(this.color.value.h, 1, 1, 1));
|
||||
this.picker.find('.colorpicker-alpha').css('backgroundColor', this.color.toHex());
|
||||
this.picker.find('.colorpicker-color, .colorpicker-color div').css('backgroundColor', this.color.toString(this.format));
|
||||
return val;
|
||||
},
|
||||
updateComponent: function(val) {
|
||||
val = val || this.color.toString(this.format);
|
||||
if (this.component !== false) {
|
||||
var icn = this.component.find('i').eq(0);
|
||||
if (icn.length > 0) {
|
||||
icn.css({
|
||||
'backgroundColor': val
|
||||
});
|
||||
} else {
|
||||
this.component.css({
|
||||
'backgroundColor': val
|
||||
});
|
||||
}
|
||||
}
|
||||
return val;
|
||||
},
|
||||
update: function(force) {
|
||||
var val = this.updateComponent();
|
||||
if ((this.getValue(false) !== false) || (force === true)) {
|
||||
// Update input/data only if the current value is not blank
|
||||
this.updateInput(val);
|
||||
this.updateData(val);
|
||||
}
|
||||
this.updatePicker();
|
||||
return val;
|
||||
|
||||
},
|
||||
setValue: function(val) { // set color manually
|
||||
this.color = new Color(val);
|
||||
this.update();
|
||||
this.element.trigger({
|
||||
type: 'changeColor',
|
||||
color: this.color,
|
||||
value: val
|
||||
});
|
||||
},
|
||||
getValue: function(defaultValue) {
|
||||
defaultValue = (defaultValue === undefined) ? '#000000' : defaultValue;
|
||||
var val;
|
||||
if (this.hasInput()) {
|
||||
val = this.input.val();
|
||||
} else {
|
||||
val = this.element.data('color');
|
||||
}
|
||||
if ((val === undefined) || (val === '') || (val === null)) {
|
||||
// if not defined or empty, return default
|
||||
val = defaultValue;
|
||||
}
|
||||
return val;
|
||||
},
|
||||
hasInput: function() {
|
||||
return (this.input !== false);
|
||||
},
|
||||
isDisabled: function() {
|
||||
if (this.hasInput()) {
|
||||
return (this.input.prop('disabled') === true);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
disable: function() {
|
||||
if (this.hasInput()) {
|
||||
this.input.prop('disabled', true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
enable: function() {
|
||||
if (this.hasInput()) {
|
||||
this.input.prop('disabled', false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
currentSlider: null,
|
||||
mousePointer: {
|
||||
left: 0,
|
||||
top: 0
|
||||
},
|
||||
mousedown: function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
var target = $(e.target);
|
||||
|
||||
//detect the slider and set the limits and callbacks
|
||||
var zone = target.closest('div');
|
||||
var sl = this.options.horizontal ? this.options.slidersHorz : this.options.sliders;
|
||||
if (!zone.is('.colorpicker')) {
|
||||
if (zone.is('.colorpicker-saturation')) {
|
||||
this.currentSlider = $.extend({}, sl.saturation);
|
||||
} else if (zone.is('.colorpicker-hue')) {
|
||||
this.currentSlider = $.extend({}, sl.hue);
|
||||
} else if (zone.is('.colorpicker-alpha')) {
|
||||
this.currentSlider = $.extend({}, sl.alpha);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
var offset = zone.offset();
|
||||
//reference to guide's style
|
||||
this.currentSlider.guide = zone.find('i')[0].style;
|
||||
this.currentSlider.left = e.pageX - offset.left;
|
||||
this.currentSlider.top = e.pageY - offset.top;
|
||||
this.mousePointer = {
|
||||
left: e.pageX,
|
||||
top: e.pageY
|
||||
};
|
||||
//trigger mousemove to move the guide to the current position
|
||||
$(document).on({
|
||||
'mousemove.colorpicker': $.proxy(this.mousemove, this),
|
||||
'mouseup.colorpicker': $.proxy(this.mouseup, this)
|
||||
}).trigger('mousemove');
|
||||
}
|
||||
return false;
|
||||
},
|
||||
mousemove: function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
var left = Math.max(
|
||||
0,
|
||||
Math.min(
|
||||
this.currentSlider.maxLeft,
|
||||
this.currentSlider.left + ((e.pageX || this.mousePointer.left) - this.mousePointer.left)
|
||||
)
|
||||
);
|
||||
var top = Math.max(
|
||||
0,
|
||||
Math.min(
|
||||
this.currentSlider.maxTop,
|
||||
this.currentSlider.top + ((e.pageY || this.mousePointer.top) - this.mousePointer.top)
|
||||
)
|
||||
);
|
||||
this.currentSlider.guide.left = left + 'px';
|
||||
this.currentSlider.guide.top = top + 'px';
|
||||
if (this.currentSlider.callLeft) {
|
||||
this.color[this.currentSlider.callLeft].call(this.color, left / 100);
|
||||
}
|
||||
if (this.currentSlider.callTop) {
|
||||
this.color[this.currentSlider.callTop].call(this.color, top / 100);
|
||||
}
|
||||
this.update(true);
|
||||
|
||||
this.element.trigger({
|
||||
type: 'changeColor',
|
||||
color: this.color
|
||||
});
|
||||
return false;
|
||||
},
|
||||
mouseup: function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
$(document).off({
|
||||
'mousemove.colorpicker': this.mousemove,
|
||||
'mouseup.colorpicker': this.mouseup
|
||||
});
|
||||
return false;
|
||||
},
|
||||
keyup: function(e) {
|
||||
if ((e.keyCode === 38)) {
|
||||
if (this.color.value.a < 1) {
|
||||
this.color.value.a = Math.round((this.color.value.a + 0.01) * 100) / 100;
|
||||
}
|
||||
this.update(true);
|
||||
} else if ((e.keyCode === 40)) {
|
||||
if (this.color.value.a > 0) {
|
||||
this.color.value.a = Math.round((this.color.value.a - 0.01) * 100) / 100;
|
||||
}
|
||||
this.update(true);
|
||||
} else {
|
||||
var val = this.input.val();
|
||||
this.color = new Color(val);
|
||||
if (this.getValue(false) !== false) {
|
||||
this.updateData();
|
||||
this.updateComponent();
|
||||
this.updatePicker();
|
||||
}
|
||||
}
|
||||
this.element.trigger({
|
||||
type: 'changeColor',
|
||||
color: this.color,
|
||||
value: val
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$.colorpicker = Colorpicker;
|
||||
|
||||
$.fn.colorpicker = function(option) {
|
||||
var pickerArgs = arguments;
|
||||
|
||||
return this.each(function() {
|
||||
var $this = $(this),
|
||||
inst = $this.data('colorpicker'),
|
||||
options = ((typeof option === 'object') ? option : {});
|
||||
if ((!inst) && (typeof option !== 'string')) {
|
||||
$this.data('colorpicker', new Colorpicker(this, options));
|
||||
} else {
|
||||
if (typeof option === 'string') {
|
||||
inst[option].apply(inst, Array.prototype.slice.call(pickerArgs, 1));
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.colorpicker.constructor = Colorpicker;
|
||||
|
||||
})(window.jQuery);
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -1,110 +0,0 @@
|
||||
/*
|
||||
* jQuery Hotkeys Plugin
|
||||
* Copyright 2010, John Resig
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
*
|
||||
* Based upon the plugin by Tzury Bar Yochay:
|
||||
* http://github.com/tzuryby/hotkeys
|
||||
*
|
||||
* Original idea by:
|
||||
* Binny V A, http://www.openjs.com/scripts/events/keyboard_shortcuts/
|
||||
*/
|
||||
|
||||
/*
|
||||
* One small change is: now keys are passed by object { keys: '...' }
|
||||
* Might be useful, when you want to pass some other data to your handler
|
||||
*/
|
||||
|
||||
(function(jQuery){
|
||||
|
||||
jQuery.hotkeys = {
|
||||
version: "0.8",
|
||||
|
||||
specialKeys: {
|
||||
8: "backspace", 9: "tab", 10: "return", 13: "enter", 16: "shift", 17: "ctrl", 18: "alt", 19: "pause",
|
||||
20: "capslock", 27: "esc", 32: "space", 33: "pageup", 34: "pagedown", 35: "end", 36: "home",
|
||||
37: "left", 38: "up", 39: "right", 40: "down", 45: "insert", 46: "del",
|
||||
96: "0", 97: "1", 98: "2", 99: "3", 100: "4", 101: "5", 102: "6", 103: "7",
|
||||
104: "8", 105: "9", 106: "*", 107: "+", 109: "-", 110: ".", 111 : "/",
|
||||
112: "f1", 113: "f2", 114: "f3", 115: "f4", 116: "f5", 117: "f6", 118: "f7", 119: "f8",
|
||||
120: "f9", 121: "f10", 122: "f11", 123: "f12", 144: "numlock", 145: "scroll", 186: ";", 191: "/",
|
||||
220: "\\", 222: "'", 224: "meta"
|
||||
},
|
||||
|
||||
shiftNums: {
|
||||
"`": "~", "1": "!", "2": "@", "3": "#", "4": "$", "5": "%", "6": "^", "7": "&",
|
||||
"8": "*", "9": "(", "0": ")", "-": "_", "=": "+", ";": ": ", "'": "\"", ",": "<",
|
||||
".": ">", "/": "?", "\\": "|"
|
||||
}
|
||||
};
|
||||
|
||||
function keyHandler( handleObj ) {
|
||||
if ( typeof handleObj.data === "string" ) {
|
||||
handleObj.data = { keys: handleObj.data };
|
||||
}
|
||||
|
||||
// Only care when a possible input has been specified
|
||||
if ( !handleObj.data || !handleObj.data.keys || typeof handleObj.data.keys !== "string" ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var origHandler = handleObj.handler,
|
||||
keys = handleObj.data.keys.toLowerCase().split(" "),
|
||||
textAcceptingInputTypes = ["text", "password", "number", "email", "url", "range", "date", "month", "week", "time", "datetime", "datetime-local", "search", "color", "tel"];
|
||||
|
||||
handleObj.handler = function( event ) {
|
||||
// Don't fire in text-accepting inputs that we didn't directly bind to
|
||||
if ( this !== event.target && (/textarea|select/i.test( event.target.nodeName ) ||
|
||||
jQuery.inArray(event.target.type, textAcceptingInputTypes) > -1 ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var special = jQuery.hotkeys.specialKeys[ event.keyCode ],
|
||||
character = String.fromCharCode( event.which ).toLowerCase(),
|
||||
modif = "", possible = {};
|
||||
|
||||
// check combinations (alt|ctrl|shift+anything)
|
||||
if ( event.altKey && special !== "alt" ) {
|
||||
modif += "alt+";
|
||||
}
|
||||
|
||||
if ( event.ctrlKey && special !== "ctrl" ) {
|
||||
modif += "ctrl+";
|
||||
}
|
||||
|
||||
// TODO: Need to make sure this works consistently across platforms
|
||||
if ( event.metaKey && !event.ctrlKey && special !== "meta" ) {
|
||||
modif += "meta+";
|
||||
}
|
||||
|
||||
if ( event.shiftKey && special !== "shift" ) {
|
||||
modif += "shift+";
|
||||
}
|
||||
|
||||
if ( special ) {
|
||||
possible[ modif + special ] = true;
|
||||
}
|
||||
|
||||
if ( character ) {
|
||||
possible[ modif + character ] = true;
|
||||
possible[ modif + jQuery.hotkeys.shiftNums[ character ] ] = true;
|
||||
|
||||
// "$" can be triggered as "Shift+4" or "Shift+$" or just "$"
|
||||
if ( modif === "shift+" ) {
|
||||
possible[ jQuery.hotkeys.shiftNums[ character ] ] = true;
|
||||
}
|
||||
}
|
||||
|
||||
for ( var i = 0, l = keys.length; i < l; i++ ) {
|
||||
if ( possible[ keys[i] ] ) {
|
||||
return origHandler.apply( this, arguments );
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
jQuery.each([ "keydown", "keyup", "keypress" ], function() {
|
||||
jQuery.event.special[ this ] = { add: keyHandler };
|
||||
});
|
||||
|
||||
})( this.jQuery );
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -1,8 +0,0 @@
|
||||
/*! Copyright (c) 2013 Brandon Aaron (http://brandon.aaron.sh)
|
||||
* Licensed under the MIT License (LICENSE.txt).
|
||||
*
|
||||
* Version: 3.1.11
|
||||
*
|
||||
* Requires: jQuery 1.2.2+
|
||||
*/
|
||||
!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?module.exports=a:a(jQuery)}(function(a){function b(b){var g=b||window.event,h=i.call(arguments,1),j=0,l=0,m=0,n=0,o=0,p=0;if(b=a.event.fix(g),b.type="mousewheel","detail"in g&&(m=-1*g.detail),"wheelDelta"in g&&(m=g.wheelDelta),"wheelDeltaY"in g&&(m=g.wheelDeltaY),"wheelDeltaX"in g&&(l=-1*g.wheelDeltaX),"axis"in g&&g.axis===g.HORIZONTAL_AXIS&&(l=-1*m,m=0),j=0===m?l:m,"deltaY"in g&&(m=-1*g.deltaY,j=m),"deltaX"in g&&(l=g.deltaX,0===m&&(j=-1*l)),0!==m||0!==l){if(1===g.deltaMode){var q=a.data(this,"mousewheel-line-height");j*=q,m*=q,l*=q}else if(2===g.deltaMode){var r=a.data(this,"mousewheel-page-height");j*=r,m*=r,l*=r}if(n=Math.max(Math.abs(m),Math.abs(l)),(!f||f>n)&&(f=n,d(g,n)&&(f/=40)),d(g,n)&&(j/=40,l/=40,m/=40),j=Math[j>=1?"floor":"ceil"](j/f),l=Math[l>=1?"floor":"ceil"](l/f),m=Math[m>=1?"floor":"ceil"](m/f),k.settings.normalizeOffset&&this.getBoundingClientRect){var s=this.getBoundingClientRect();o=b.clientX-s.left,p=b.clientY-s.top}return b.deltaX=l,b.deltaY=m,b.deltaFactor=f,b.offsetX=o,b.offsetY=p,b.deltaMode=0,h.unshift(b,j,l,m),e&&clearTimeout(e),e=setTimeout(c,200),(a.event.dispatch||a.event.handle).apply(this,h)}}function c(){f=null}function d(a,b){return k.settings.adjustOldDeltas&&"mousewheel"===a.type&&b%120===0}var e,f,g=["wheel","mousewheel","DOMMouseScroll","MozMousePixelScroll"],h="onwheel"in document||document.documentMode>=9?["wheel"]:["mousewheel","DomMouseScroll","MozMousePixelScroll"],i=Array.prototype.slice;if(a.event.fixHooks)for(var j=g.length;j;)a.event.fixHooks[g[--j]]=a.event.mouseHooks;var k=a.event.special.mousewheel={version:"3.1.11",setup:function(){if(this.addEventListener)for(var c=h.length;c;)this.addEventListener(h[--c],b,!1);else this.onmousewheel=b;a.data(this,"mousewheel-line-height",k.getLineHeight(this)),a.data(this,"mousewheel-page-height",k.getPageHeight(this))},teardown:function(){if(this.removeEventListener)for(var c=h.length;c;)this.removeEventListener(h[--c],b,!1);else this.onmousewheel=null;a.removeData(this,"mousewheel-line-height"),a.removeData(this,"mousewheel-page-height")},getLineHeight:function(b){var c=a(b)["offsetParent"in a.fn?"offsetParent":"parent"]();return c.length||(c=a("body")),parseInt(c.css("fontSize"),10)},getPageHeight:function(b){return a(b).height()},settings:{adjustOldDeltas:!0,normalizeOffset:!0}};a.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})});
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user