Commit 6b25e103 authored by techird's avatar techird

merge

parents 71e6130a a65a0432
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
"utils", "utils",
"$", "$",
"KM", "KM",
"keymap" "keymap",
"baidu"
] ]
} }
\ No newline at end of file
(function(){ ( function () {
function getKMBasePath ( docUrl, confUrl ) { function getKMBasePath( docUrl, confUrl ) {
return getBasePath( docUrl || self.document.URL || self.location.href, confUrl || getConfigFilePath() ); return getBasePath( docUrl || self.document.URL || self.location.href, confUrl || getConfigFilePath() );
} }
function getConfigFilePath () { function getConfigFilePath() {
var configPath = document.getElementsByTagName('script'); var configPath = document.getElementsByTagName( 'script' );
return configPath[ configPath.length -1 ].src; return configPath[ configPath.length - 1 ].src;
} }
function getBasePath ( docUrl, confUrl ) { function getBasePath( docUrl, confUrl ) {
var basePath = confUrl; var basePath = confUrl;
if(/^(\/|\\\\)/.test(confUrl)){ if ( /^(\/|\\\\)/.test( confUrl ) ) {
basePath = /^.+?\w(\/|\\\\)/.exec(docUrl)[0] + confUrl.replace(/^(\/|\\\\)/,''); basePath = /^.+?\w(\/|\\\\)/.exec( docUrl )[ 0 ] + confUrl.replace( /^(\/|\\\\)/, '' );
}else if ( !/^[a-z]+:/i.test( confUrl ) ) { } else if ( !/^[a-z]+:/i.test( confUrl ) ) {
docUrl = docUrl.split( "#" )[0].split( "?" )[0].replace( /[^\\\/]+$/, '' ); docUrl = docUrl.split( "#" )[ 0 ].split( "?" )[ 0 ].replace( /[^\\\/]+$/, '' );
basePath = docUrl + "" + confUrl; basePath = docUrl + "" + confUrl;
...@@ -34,15 +34,15 @@ ...@@ -34,15 +34,15 @@
} }
function optimizationPath ( path ) { function optimizationPath( path ) {
var protocol = /^[a-z]+:\/\//.exec( path )[ 0 ], var protocol = /^[a-z]+:\/\//.exec( path )[ 0 ],
tmp = null, tmp = null,
res = []; res = [];
path = path.replace( protocol, "" ).split( "?" )[0].split( "#" )[0]; path = path.replace( protocol, "" ).split( "?" )[ 0 ].split( "#" )[ 0 ];
path = path.replace( /\\/g, '/').split( /\// ); path = path.replace( /\\/g, '/' ).split( /\// );
path[ path.length - 1 ] = ""; path[ path.length - 1 ] = "";
...@@ -63,7 +63,7 @@ ...@@ -63,7 +63,7 @@
'KITYMINDER_HOME_URL': getKMBasePath(), 'KITYMINDER_HOME_URL': getKMBasePath(),
//定义工具栏 //定义工具栏
toolbars: [ toolbars: [
'hand zoom-in zoom-out | undo redo | bold italic | fontfamily fontsize forecolor | saveto | markers' 'hand zoom-in zoom-out | undo redo | bold italic | fontfamily fontsize forecolor | saveto | markers | node | switchlayout'
] ]
//设置主题 //设置主题
...@@ -79,4 +79,4 @@ ...@@ -79,4 +79,4 @@
//设置km整体的z-index大小 //设置km整体的z-index大小
//,zIndex : 1000 //,zIndex : 1000
}; };
})() } )()
\ No newline at end of file
...@@ -827,6 +827,9 @@ var Minder = KityMinder.Minder = kity.createClass( "KityMinder", { ...@@ -827,6 +827,9 @@ var Minder = KityMinder.Minder = kity.createClass( "KityMinder", {
this._shortcutkeys = {}; this._shortcutkeys = {};
this._bindshortcutKeys(); this._bindshortcutKeys();
}, },
isTextEditStatus:function(){
return false;
},
addShortcutKeys: function ( cmd, keys ) { addShortcutKeys: function ( cmd, keys ) {
var obj = {},km = this; var obj = {},km = this;
if ( keys ) { if ( keys ) {
...@@ -845,25 +848,50 @@ var Minder = KityMinder.Minder = kity.createClass( "KityMinder", { ...@@ -845,25 +848,50 @@ var Minder = KityMinder.Minder = kity.createClass( "KityMinder", {
_bindshortcutKeys: function () { _bindshortcutKeys: function () {
var me = this, var me = this,
shortcutkeys = this._shortcutkeys; shortcutkeys = this._shortcutkeys;
me.on( 'keydown', function ( e ) { function checkkey(key,keyCode,e){
switch(key){
case 'ctrl':
case 'cmd':
if(e.ctrlKey || e.metaKey){
return true;
}
break;
case 'alt':
if(e.altKey){
return true
}
break;
case 'shift':
if(e.shiftKey){
return true;
}
}
if(keyCode == keymap[key]){
return true;
}
return false
}
me.on( 'keydown', function ( e ) {
var originEvent = e.originEvent; var originEvent = e.originEvent;
var keyCode = originEvent.keyCode || originEvent.which; var keyCode = originEvent.keyCode || originEvent.which;
for ( var i in shortcutkeys ) { for ( var i in shortcutkeys ) {
var tmp = shortcutkeys[ i ].split( ',' ); var keys = shortcutkeys[ i ].toLowerCase().split('+');
for ( var t = 0, ti; ti = tmp[ t++ ]; ) { var current = 0;
ti = ti.split( ':' ); utils.each(keys,function(i,k){
var key = ti[ 0 ], if(checkkey(k,keyCode,originEvent)){
param = ti[ 1 ]; current++;
if ( /^(ctrl)(\+shift)?\+(\d+)$/.test( key.toLowerCase() ) || /^(\d+)$/.test( key ) ) {
if ( ( ( RegExp.$1 == 'ctrl' ? ( originEvent.ctrlKey || originEvent.metaKey ) : 0 ) && ( RegExp.$2 != "" ? originEvent[ RegExp.$2.slice( 1 ) + "Key" ] : 1 ) && keyCode == RegExp.$3 ) ||
keyCode == RegExp.$1
) {
if ( me.queryCommandState( i, param ) != -1 )
me.execCommand( i, param );
e.preventDefault();
} }
});
//todo 暂时通过receiver判断
if(me.isTextEditStatus()){
return;
} }
if(current == keys.length){
if ( me.queryCommandState( i ) != -1 )
me.execCommand( i );
originEvent.preventDefault();
break;
} }
} }
...@@ -1322,7 +1350,16 @@ var keymap = KityMinder.keymap = { ...@@ -1322,7 +1350,16 @@ var keymap = KityMinder.keymap = {
'NumLock':144, 'NumLock':144,
'Cmd':91 'Cmd':91,
'=':187,
'-':189,
"b":66,
'i':73,
'z':90,
'y':89
}; };
//添加多语言模块 //添加多语言模块
...@@ -1600,8 +1637,8 @@ KityMinder.registerModule( "HistoryModule", function () { ...@@ -1600,8 +1637,8 @@ KityMinder.registerModule( "HistoryModule", function () {
} ) } )
}, },
addShortcutKeys: { addShortcutKeys: {
"Undo": "ctrl+90", //undo "Undo": "ctrl+z", //undo
"Redo": "ctrl+89" //redo "Redo": "ctrl+y" //redo
}, },
"events": { "events": {
"saveScene": function ( e ) { "saveScene": function ( e ) {
...@@ -1769,7 +1806,11 @@ KityMinder.registerModule( "LayoutModule", function () { ...@@ -1769,7 +1806,11 @@ KityMinder.registerModule( "LayoutModule", function () {
return this._layoutStyles[ name ]; return this._layoutStyles[ name ];
}, },
getLayoutStyleItems: function () { getLayoutStyleItems: function () {
return this._layoutStyles; var items = [];
for ( var key in this._layoutStyles ) {
items.push( key );
}
return items;
}, },
getCurrentStyle: function () { getCurrentStyle: function () {
var _root = this.getRoot(); var _root = this.getRoot();
...@@ -1851,7 +1892,10 @@ KityMinder.registerModule( "LayoutModule", function () { ...@@ -1851,7 +1892,10 @@ KityMinder.registerModule( "LayoutModule", function () {
var SwitchLayoutCommand = kity.createClass( "SwitchLayoutCommand", ( function () { var SwitchLayoutCommand = kity.createClass( "SwitchLayoutCommand", ( function () {
return { return {
base: Command, base: Command,
execute: switchLayout execute: switchLayout,
queryValue: function ( km ) {
return km.getCurrentStyle();
}
}; };
} )() ); } )() );
var AppendChildNodeCommand = kity.createClass( "AppendChildNodeCommand", ( function () { var AppendChildNodeCommand = kity.createClass( "AppendChildNodeCommand", ( function () {
...@@ -1859,12 +1903,17 @@ KityMinder.registerModule( "LayoutModule", function () { ...@@ -1859,12 +1903,17 @@ KityMinder.registerModule( "LayoutModule", function () {
base: Command, base: Command,
execute: function ( km, node ) { execute: function ( km, node ) {
var parent = km.getSelectedNode(); var parent = km.getSelectedNode();
if ( !parent ) {
return false;
}
km.appendChildNode( parent, node ); km.appendChildNode( parent, node );
km.select( node, true ); km.select( node, true );
return node; return node;
},
queryState: function ( km ) {
var selectedNode = km.getSelectedNode();
if ( !selectedNode ) {
return -1;
} else {
return 0;
}
} }
}; };
} )() ); } )() );
...@@ -1873,9 +1922,6 @@ KityMinder.registerModule( "LayoutModule", function () { ...@@ -1873,9 +1922,6 @@ KityMinder.registerModule( "LayoutModule", function () {
base: Command, base: Command,
execute: function ( km, node ) { execute: function ( km, node ) {
var selectedNode = km.getSelectedNode(); var selectedNode = km.getSelectedNode();
if ( !selectedNode ) {
return false;
}
if ( selectedNode.isRoot() ) { if ( selectedNode.isRoot() ) {
node.setType( "main" ); node.setType( "main" );
km.appendChildNode( selectedNode, node ); km.appendChildNode( selectedNode, node );
...@@ -1885,6 +1931,15 @@ KityMinder.registerModule( "LayoutModule", function () { ...@@ -1885,6 +1931,15 @@ KityMinder.registerModule( "LayoutModule", function () {
} }
km.select( node, true ); km.select( node, true );
return node; return node;
},
queryState: function ( km ) {
var selectedNodes = km.getSelectedNodes();
//没选中节点和单选root的时候返回不可执行
if ( selectedNodes.length === 0 || ( selectedNodes.length === 1 && selectedNodes[ 0 ] === km.getRoot() ) ) {
return -1;
} else {
return 0;
}
} }
}; };
} )() ); } )() );
...@@ -1894,10 +1949,6 @@ KityMinder.registerModule( "LayoutModule", function () { ...@@ -1894,10 +1949,6 @@ KityMinder.registerModule( "LayoutModule", function () {
execute: function ( km ) { execute: function ( km ) {
var selectedNodes = km.getSelectedNodes(); var selectedNodes = km.getSelectedNodes();
var _root = km.getRoot(); var _root = km.getRoot();
if ( selectedNodes.length === 0 || ( selectedNodes.length === 1 && !selectedNodes[ 0 ].getParent() ) ) {
km.select( _root );
return false;
}
var _buffer = []; var _buffer = [];
for ( var i = 0; i < selectedNodes.length; i++ ) { for ( var i = 0; i < selectedNodes.length; i++ ) {
_buffer.push( selectedNodes[ i ] ); _buffer.push( selectedNodes[ i ] );
...@@ -1909,6 +1960,14 @@ KityMinder.registerModule( "LayoutModule", function () { ...@@ -1909,6 +1960,14 @@ KityMinder.registerModule( "LayoutModule", function () {
} while ( _buffer.length > 1 ); } while ( _buffer.length > 1 );
km.removeNode( selectedNodes ); km.removeNode( selectedNodes );
km.select( _buffer[ 0 ] ); km.select( _buffer[ 0 ] );
},
queryState: function ( km ) {
var selectedNodes = km.getSelectedNodes();
if ( selectedNodes.length === 0 || ( selectedNodes.length === 1 && selectedNodes[ 0 ] === km.getRoot() ) ) {
return -1;
} else {
return 0;
}
} }
}; };
} )() ); } )() );
...@@ -1942,7 +2001,12 @@ KityMinder.registerModule( "LayoutModule", function () { ...@@ -1942,7 +2001,12 @@ KityMinder.registerModule( "LayoutModule", function () {
} }
}, },
"defaultOptions": { "defaultOptions": {
"defaultlayoutstyle": "default" "defaultlayoutstyle": "default",
"node": {
'appendsiblingnode': 'appendsiblingnode',
'appendchildnode': 'appendchildnode',
'removenode': 'removenode'
}
} }
}; };
} ); } );
...@@ -2554,7 +2618,6 @@ KityMinder.registerModule( "LayoutDefault", function () { ...@@ -2554,7 +2618,6 @@ KityMinder.registerModule( "LayoutDefault", function () {
var parent = _buffer[ 0 ].getParent(); var parent = _buffer[ 0 ].getParent();
Layout.parent = parent; Layout.parent = parent;
_cleanbuffer.push( _buffer[ 0 ] ); _cleanbuffer.push( _buffer[ 0 ] );
//minder.appendChildNode( parent, _buffer[ 0 ] );
Layout.connect = null; Layout.connect = null;
Layout.shicon = null; Layout.shicon = null;
} else { } else {
...@@ -2603,21 +2666,24 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -2603,21 +2666,24 @@ KityMinder.registerModule( "LayoutBottom", function () {
var iconShape = this.shape = new kity.Group(); var iconShape = this.shape = new kity.Group();
iconShape.class = "shicon"; iconShape.class = "shicon";
iconShape.icon = this; iconShape.icon = this;
var circle = this._circle = new kity.Circle().fill( "white" ).stroke( "gray" ).setRadius( 5 ); var rect = this._rect = new kity.Rect().fill( "white" ).stroke( "gray" ).setRadius( 2 ).setWidth( 10 ).setHeight( 10 );
var plus = this._plus = new kity.Path(); var plus = this._plus = new kity.Path();
plus.getDrawer() plus.getDrawer()
.moveTo( -3, 0 ) .moveTo( 2, 5 )
.lineTo( 3, 0 ) .lineTo( 8, 5 )
.moveTo( 0, -3 ) .moveTo( 5, 2 )
.lineTo( 0, 3 ); .lineTo( 5, 8 );
plus.stroke( "gray" ); plus.stroke( "gray" );
var dec = this._dec = new kity.Path(); var dec = this._dec = new kity.Path();
dec.getDrawer() dec.getDrawer()
.moveTo( -3, 0 ) .moveTo( 2, 5 )
.lineTo( 3, 0 ); .lineTo( 8, 5 );
dec.stroke( "gray" ); dec.stroke( "gray" );
minder.getRenderContainer().addShape( iconShape ); if ( node.getType() === "main" ) minder.getRenderContainer().addShape( iconShape );
iconShape.addShapes( [ circle, plus, dec ] ); else {
node.getLayout().subgroup.addShape( iconShape );
}
iconShape.addShapes( [ rect, plus, dec ] );
this.update(); this.update();
this.switchState(); this.switchState();
}, },
...@@ -2637,12 +2703,9 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -2637,12 +2703,9 @@ KityMinder.registerModule( "LayoutBottom", function () {
var node = this._node; var node = this._node;
var Layout = node.getLayout(); var Layout = node.getLayout();
var nodeShape = node.getRenderContainer(); var nodeShape = node.getRenderContainer();
var nodeX, nodeY = ( node.getType() === "main" ? Layout.y : ( Layout.y + nodeShape.getHeight() / 2 - 5 ) ); var nodeType = node.getType();
if ( Layout.appendside === "left" ) { var nodeX = nodeShape.getRenderBox().closurePoints[ 1 ].x + 5;
nodeX = nodeShape.getRenderBox().closurePoints[ 1 ].x - 6; var nodeY = nodeShape.getRenderBox().closurePoints[ 0 ].y;
} else {
nodeX = nodeShape.getRenderBox().closurePoints[ 0 ].x + 6;
}
this.shape.setTransform( new kity.Matrix().translate( nodeX, nodeY ) ); this.shape.setTransform( new kity.Matrix().translate( nodeX, nodeY ) );
}, },
remove: function () { remove: function () {
...@@ -2650,16 +2713,6 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -2650,16 +2713,6 @@ KityMinder.registerModule( "LayoutBottom", function () {
} }
}; };
} )() ); } )() );
//求并集
var uSet = function ( a, b ) {
for ( var i = 0; i < a.length; i++ ) {
var idx = b.indexOf( a[ i ] );
if ( idx !== -1 ) {
b.splice( idx, 1 );
}
}
return a.concat( b );
};
//样式的配置(包括颜色、字号等) //样式的配置(包括颜色、字号等)
var nodeStyles = { var nodeStyles = {
"root": { "root": {
...@@ -2667,8 +2720,8 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -2667,8 +2720,8 @@ KityMinder.registerModule( "LayoutBottom", function () {
fill: '#e9df98', fill: '#e9df98',
fontSize: 24, fontSize: 24,
padding: [ 15.5, 25.5, 15.5, 25.5 ], padding: [ 15.5, 25.5, 15.5, 25.5 ],
margin: [ 0, 0, 0, 0 ], margin: [ 0, 0, 20, 0 ],
radius: 30, radius: 0,
highlight: 'rgb(254, 219, 0)' highlight: 'rgb(254, 219, 0)'
}, },
"main": { "main": {
...@@ -2677,17 +2730,18 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -2677,17 +2730,18 @@ KityMinder.registerModule( "LayoutBottom", function () {
color: "#333", color: "#333",
padding: [ 6.5, 20, 6.5, 20 ], padding: [ 6.5, 20, 6.5, 20 ],
fontSize: 16, fontSize: 16,
margin: [ 0, 10, 30, 50 ], margin: [ 20, 20, 10, 10 ],
radius: 10, radius: 0,
highlight: 'rgb(254, 219, 0)' highlight: 'rgb(254, 219, 0)'
}, },
"sub": { "sub": {
stroke: new kity.Pen( "white", 2 ).setLineCap( "round" ).setLineJoin( "round" ), stroke: new kity.Pen( "white", 2 ).setLineCap( "round" ).setLineJoin( "round" ),
color: "white", color: "#333",
fontSize: 12, fontSize: 12,
margin: [ 0, 10, 20, 6 ], margin: [ 10, 10, 10, 30 ],
padding: [ 5, 10, 5.5, 10 ], padding: [ 5, 10, 5.5, 10 ],
highlight: 'rgb(254, 219, 0)' highlight: 'rgb(254, 219, 0)',
fill: 'rgb(231, 243, 255)'
} }
}; };
//更新背景 //更新背景
...@@ -2705,9 +2759,9 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -2705,9 +2759,9 @@ KityMinder.registerModule( "LayoutBottom", function () {
Layout.bgShadow.fill( 'black' ).setOpacity( 0.2 ).setRadius( nodeStyle.radius ).translate( 3, 5 ); Layout.bgShadow.fill( 'black' ).setOpacity( 0.2 ).setRadius( nodeStyle.radius ).translate( 3, 5 );
break; break;
case "sub": case "sub":
var underline = Layout.underline = new kity.Path(); var bgRc = node.getBgRc().clear();
var highlightshape = Layout.highlightshape = new kity.Rect().setRadius( 4 ); bgRc.addShape( Layout.bgRect = new kity.Rect() );
node.getBgRc().clear().addShapes( [ Layout.bgRect = new kity.Rect().setRadius( 4 ), highlightshape, underline ] ); Layout.bgRect.fill( nodeStyle.fill );
break; break;
default: default:
break; break;
...@@ -2720,6 +2774,10 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -2720,6 +2774,10 @@ KityMinder.registerModule( "LayoutBottom", function () {
var nodeStyle = nodeStyles[ nodeType ]; var nodeStyle = nodeStyles[ nodeType ];
var txtShape = node.getTextShape(); var txtShape = node.getTextShape();
txtShape.fill( nodeStyle.color ).setSize( nodeStyle.fontSize ).setY( -3 ); txtShape.fill( nodeStyle.color ).setSize( nodeStyle.fontSize ).setY( -3 );
if ( nodeType === "main" ) {
var subgroup = Layout.subgroup = new kity.Group();
minder.getRenderContainer().addShape( subgroup );
}
}; };
//根据内容调整节点尺寸 //根据内容调整节点尺寸
var updateShapeByCont = function ( node ) { var updateShapeByCont = function ( node ) {
...@@ -2738,18 +2796,8 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -2738,18 +2796,8 @@ KityMinder.registerModule( "LayoutBottom", function () {
Layout.bgShadow.setWidth( width ).setHeight( height ); Layout.bgShadow.setWidth( width ).setHeight( height );
break; break;
case "sub": case "sub":
var _contWidth = contRc.getWidth(); width = _contRCWidth + nodeStyle.padding[ 1 ] + nodeStyle.padding[ 3 ];
var _contHeight = contRc.getHeight(); height = _contRCHeight + nodeStyle.padding[ 0 ] + nodeStyle.padding[ 2 ];
width = _contWidth + nodeStyle.padding[ 1 ] + nodeStyle.padding[ 3 ];
height = _contHeight + nodeStyle.padding[ 0 ] + nodeStyle.padding[ 2 ];
Layout.underline.getDrawer()
.clear()
.moveTo( 0, _contHeight + nodeStyle.padding[ 2 ] + nodeStyle.padding[ 0 ] )
.lineTo( _contWidth + nodeStyle.padding[ 1 ] + nodeStyle.padding[ 3 ], _contHeight + nodeStyle.padding[ 2 ] + nodeStyle.padding[ 0 ] );
Layout.underline.stroke( nodeStyle.stroke );
Layout.highlightshape
.setWidth( _contWidth + nodeStyle.padding[ 1 ] + nodeStyle.padding[ 3 ] )
.setHeight( _contHeight + nodeStyle.padding[ 0 ] + nodeStyle.padding[ 2 ] );
Layout.bgRect.setWidth( width ).setHeight( height ); Layout.bgRect.setWidth( width ).setHeight( height );
break; break;
default: default:
...@@ -2757,87 +2805,95 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -2757,87 +2805,95 @@ KityMinder.registerModule( "LayoutBottom", function () {
} }
contRc.setTransform( new kity.Matrix().translate( nodeStyle.padding[ 3 ], nodeStyle.padding[ 0 ] + node.getTextShape().getHeight() ) ); contRc.setTransform( new kity.Matrix().translate( nodeStyle.padding[ 3 ], nodeStyle.padding[ 0 ] + node.getTextShape().getHeight() ) );
}; };
//计算节点在垂直方向的位置 var updateLayoutMain = function () {
var updateLayoutVertical = function ( node ) { var _root = minder.getRoot();
var mainnodes = _root.getChildren();
var countMainWidth = function ( node ) {
var nLayout = node.getLayout();
var selfwidth = node.getRenderContainer().getWidth() + nodeStyles.main.margin[ 1 ] + nodeStyles.main.margin[ 3 ];
var childwidth = nLayout.subgroup.getWidth() + nodeStyles.main.margin[ 1 ] + nodeStyles.sub.margin[ 3 ];
var branchwidth = nLayout.branchwidth = ( selfwidth > childwidth ? selfwidth : childwidth );
return branchwidth;
};
var rootLayout = _root.getLayout();
var rootbranchwidth = 0;
for ( var j = 0; j < mainnodes.length; j++ ) {
rootbranchwidth += countMainWidth( mainnodes[ j ] );
}
var sX = rootLayout.x - rootbranchwidth / 2;
for ( var k = 0; k < mainnodes.length; k++ ) {
var mLayout = mainnodes[ k ].getLayout();
mLayout.x = sX;
sX += mLayout.branchwidth;
}
return mainnodes;
};
var updateLayoutAll = function ( node, parent, action ) {
var effectSet = [];
var nodeType = node.getType(); var nodeType = node.getType();
var parent = node.getParent();
var effectSet = [ node ];
var Layout = node.getLayout(); var Layout = node.getLayout();
var _buffer = [ node ]; var _root = minder.getRoot();
while ( _buffer.length !== 0 ) { var rootLayout = _root.getLayout();
var prt = _buffer[ 0 ].getParent(); if ( nodeType === "root" ) {
_buffer = _buffer.concat( _buffer[ 0 ].getChildren() ); Layout.x = getMinderSize().width / 2;
if ( !prt ) {
Layout.y = 100; Layout.y = 100;
_buffer.shift(); Layout.align = "center";
continue; effectSet.push( node );
}
var parentLayout = prt.getLayout();
var parentHeight = prt.getRenderContainer().getHeight();
var parentStyle = nodeStyles[ prt.getType() ];
var childLayout = _buffer[ 0 ].getLayout();
var childStyle = nodeStyles[ _buffer[ 0 ].getType() ];
childLayout.y = parentLayout.y + parentHeight + parentStyle.margin[ 2 ] + childStyle.margin[ 2 ];
effectSet.push( _buffer[ 0 ] );
_buffer.shift();
}
return effectSet;
};
//计算节点在水平方向的位置
var updateLayoutHorizon = function ( node, parent, action ) {
var root = minder.getRoot();
var effectSet = [ node ];
if ( action === "remove" ) {
effectSet = [];
}
var Layout = node.getLayout();
var nodeShape = node.getRenderContainer();
var nodeType = node.getType();
var nodeStyle = nodeStyles[ nodeType ];
var countBranchWidth = function ( node ) {
var nodeStyle = nodeStyles[ node.getType() ];
var selfWidth = node.getRenderContainer().getWidth() + nodeStyle.margin[ 1 ] + nodeStyle.margin[ 3 ];
var childWidth = ( function () {
var sum = 0;
var children = node.getChildren(); var children = node.getChildren();
for ( var i = 0; i < children.length; i++ ) { for ( var i = 0; i < children.length; i++ ) {
var childLayout = children[ i ].getLayout(); var childLayout = children[ i ].getLayout();
if ( children[ i ].getRenderContainer().getWidth() !== 0 ) childLayout.y = Layout.y + node.getRenderContainer().getHeight() + nodeStyles.root.margin[ 2 ] + nodeStyles.main.margin[ 0 ];
sum += childLayout.branchwidth;
} }
return sum; effectSet = effectSet.concat( children );
} )(); } else if ( nodeType === "main" ) {
return ( selfWidth > childWidth ? selfWidth : childWidth ); Layout.align = "left";
};
if ( nodeType === "root" ) {
Layout.x = getMinderSize().width / 2 - node.getRenderContainer().getWidth() / 2;
effectSet.push( node );
} else {
if ( action === "append" || action === "contract" ) { if ( action === "append" || action === "contract" ) {
Layout.branchwidth = node.getRenderContainer().getWidth() + nodeStyle.margin[ 1 ] + nodeStyle.margin[ 3 ]; Layout.y = rootLayout.y + _root.getRenderContainer().getHeight() + nodeStyles.root.margin[ 2 ] + nodeStyles.main.margin[ 0 ];
} else if ( action === "change" ) {
Layout.branchheight = countBranchWidth( node );
} }
effectSet = updateLayoutMain();
} else {
Layout.align = "left";
var parentLayout = parent.getLayout(); var parentLayout = parent.getLayout();
var parentShape = parent.getRenderContainer(); if ( action === "append" ) {
var prt = node.getParent() || parent; if ( parent.getType() === "main" ) {
//自底向上更新祖先元素的branchwidth值 Layout.x = nodeStyles.sub.margin[ 3 ];
while ( prt ) { } else {
Layout.x = parentLayout.x + nodeStyles.sub.margin[ 3 ];
}
}
if ( action === "append" || action === "contract" ) {
Layout.branchheight = node.getRenderContainer().getHeight() + nodeStyles.sub.margin[ 0 ] + nodeStyles.sub.margin[ 2 ];
}
var prt = parent;
if ( action === "change" ) {
prt = node;
}
//自底向上更新branchheight
while ( prt.getType() !== "main" ) {
var c = prt.getChildren();
var prtLayout = prt.getLayout(); var prtLayout = prt.getLayout();
prtLayout.branchheight = countBranchWidth( prt ); var branchHeight = prt.getRenderContainer().getHeight() + nodeStyles.sub.margin[ 0 ] + nodeStyles.sub.margin[ 2 ];
for ( var i1 = 0; i1 < c.length; i1++ ) {
branchHeight += c[ i1 ].getLayout().branchheight;
}
prtLayout.branchheight = branchHeight;
prt = prt.getParent(); prt = prt.getParent();
} }
//自顶向下更新受影响一侧的y值 //自顶向下更新y
var _buffer = [ root ]; var _buffer = [ prt ];
while ( _buffer.length > 0 ) { while ( _buffer.length !== 0 ) {
var childrenC = _buffer[ 0 ].getChildren();
_buffer = _buffer.concat( childrenC );
var _buffer0Layout = _buffer[ 0 ].getLayout(); var _buffer0Layout = _buffer[ 0 ].getLayout();
var children = _buffer[ 0 ].getChildren(); var _buffer0Style = nodeStyles[ _buffer[ 0 ].getType() ];
_buffer = _buffer.concat( children ); var sY;
var sX = _buffer0Layout.x - _buffer0Layout.branchwidth / 2; if ( _buffer[ 0 ].getType() === "main" ) sY = 0;
for ( var i = 0; i < children.length; i++ ) { else sY = _buffer0Layout.y + _buffer[ 0 ].getRenderContainer().getHeight() + _buffer0Style.margin[ 2 ];
var childLayout = children[ i ].getLayout(); for ( var s = 0; s < childrenC.length; s++ ) {
childLayout.x = sX; var childLayoutC = childrenC[ s ].getLayout();
sX += childLayout.branchwidth; var childStyleC = nodeStyles[ childrenC[ s ].getType() ];
childLayoutC.y = sY + childStyleC.margin[ 0 ];
sY += childLayoutC.branchheight;
} }
effectSet.push( _buffer[ 0 ] ); effectSet.push( _buffer[ 0 ] );
_buffer.shift(); _buffer.shift();
...@@ -2851,7 +2907,20 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -2851,7 +2907,20 @@ KityMinder.registerModule( "LayoutBottom", function () {
var align = Layout.align; var align = Layout.align;
var _rectHeight = nodeShape.getHeight(); var _rectHeight = nodeShape.getHeight();
var _rectWidth = nodeShape.getWidth(); var _rectWidth = nodeShape.getWidth();
switch ( align ) {
case "right":
nodeShape.setTransform( new kity.Matrix().translate( Layout.x - _rectWidth, Layout.y ) );
break;
case "center":
nodeShape.setTransform( new kity.Matrix().translate( Layout.x - _rectWidth / 2, Layout.y ) );
break;
default:
nodeShape.setTransform( new kity.Matrix().translate( Layout.x, Layout.y ) ); nodeShape.setTransform( new kity.Matrix().translate( Layout.x, Layout.y ) );
break;
}
if ( node.getType() === "main" ) {
Layout.subgroup.setTransform( new kity.Matrix().translate( Layout.x, Layout.y + node.getRenderContainer().getHeight() ) );
}
node.setPoint( Layout.x, Layout.y ); node.setPoint( Layout.x, Layout.y );
}; };
var updateConnectAndshIcon = function ( node ) { var updateConnectAndshIcon = function ( node ) {
...@@ -2859,73 +2928,50 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -2859,73 +2928,50 @@ KityMinder.registerModule( "LayoutBottom", function () {
var Layout = node.getLayout(); var Layout = node.getLayout();
var nodeStyle = nodeStyles[ node.getType() ]; var nodeStyle = nodeStyles[ node.getType() ];
var connect; var connect;
var _root = minder.getRoot();
var _rootLayout = _root.getLayout();
//更新连线 //更新连线
if ( nodeType === "main" ) { if ( nodeType === "main" ) {
if ( !Layout.connect ) { if ( !Layout.connect ) {
connect = Layout.connect = new kity.Group(); connect = Layout.connect = new kity.Path();
var bezier = Layout.connect.bezier = new kity.Bezier();
var circle = Layout.connect.circle = new kity.Circle();
connect.addShapes( [ bezier, circle ] );
minder.getRenderContainer().addShape( connect ); minder.getRenderContainer().addShape( connect );
minder.getRoot().getRenderContainer().bringTop();
} }
var parent = minder.getRoot();
var rootX = parent.getLayout().x;
var rootY = parent.getLayout().y;
connect = Layout.connect; connect = Layout.connect;
var nodeShape = node.getRenderContainer(); var sX = _rootLayout.x;
var nodeClosurePoints = nodeShape.getRenderBox().closurePoints; var sY = _rootLayout.y + _root.getRenderContainer().getHeight();
var sPos; var transX = Layout.x + node.getRenderContainer().getWidth() / 2;
var endPos; var transY = sY + nodeStyles.root.margin[ 2 ];
if ( Layout.appendside === "left" ) { connect.getDrawer().clear()
sPos = new kity.BezierPoint( rootX - 30, nodeClosurePoints[ 2 ].y + nodeShape.getHeight() / 2 ); .moveTo( sX, sY )
endPos = new kity.BezierPoint( nodeClosurePoints[ 2 ].x + 3, nodeClosurePoints[ 2 ].y + nodeShape.getHeight() / 2 ); .lineTo( sX, transY )
} else { .lineTo( transX, transY )
sPos = new kity.BezierPoint( rootX + 30, nodeClosurePoints[ 3 ].y + nodeShape.getHeight() / 2 ); .lineTo( transX, Layout.y );
endPos = new kity.BezierPoint( nodeClosurePoints[ 3 ].x - 3, nodeClosurePoints[ 3 ].y + nodeShape.getHeight() / 2 ); connect.stroke( nodeStyles.main.stroke );
}
var sPosV = sPos.getVertex();
var endPosV = endPos.getVertex();
sPos.setVertex( rootX, rootY );
connect.bezier.setPoints( [ sPos, endPos ] ).stroke( nodeStyle.stroke );
connect.circle.setCenter( endPosV.x + ( Layout.appendside === "left" ? 1 : -1.5 ), endPosV.y ).fill( "white" ).setRadius( 4 );
} else if ( nodeType === "sub" ) { } else if ( nodeType === "sub" ) {
var parent = node.getParent();
var parentLayout = parent.getLayout();
if ( !Layout.connect ) { if ( !Layout.connect ) {
connect = Layout.connect = new kity.Path(); connect = Layout.connect = new kity.Path();
minder.getRenderContainer().addShape( connect ); Layout.subgroup.addShape( connect );
} }
connect = Layout.connect; connect = Layout.connect;
var parentShape = node.getParent().getRenderContainer(); var ssX, ssY;
var parentBox = parentShape.getRenderBox(); if ( parent.getType() === "main" ) {
var parentLayout = node.getParent().getLayout(); ssX = 10;
var parentStyle = nodeStyles[ node.getParent().getType() ]; ssY = 0;
var Shape = node.getRenderContainer();
var sX, sY = parentLayout.y;
var nodeX, nodeY = Shape.getRenderBox().closurePoints[ 1 ].y;
if ( Layout.appendside === "left" ) {
sX = parentBox.closurePoints[ 1 ].x - parentStyle.margin[ 1 ];
nodeX = Shape.getRenderBox().closurePoints[ 0 ].x;
connect.getDrawer()
.clear()
.moveTo( sX, sY )
.lineTo( sX, nodeY > sY ? ( nodeY - nodeStyle.margin[ 3 ] ) : ( nodeY + nodeStyle.margin[ 3 ] ) );
if ( nodeY > sY ) connect.getDrawer().carcTo( nodeStyle.margin[ 3 ], nodeX, nodeY, 0, 1 );
else connect.getDrawer().carcTo( nodeStyle.margin[ 3 ], nodeX, nodeY );
connect.stroke( nodeStyle.stroke );
} else { } else {
sX = parentBox.closurePoints[ 0 ].x + parentStyle.margin[ 1 ]; ssX = parentLayout.x + 10;
nodeX = Shape.getRenderBox().closurePoints[ 1 ].x + 1; ssY = parentLayout.y + parent.getRenderContainer().getHeight() + 10;
connect.getDrawer()
.clear()
.moveTo( sX, sY )
.lineTo( sX, nodeY > sY ? ( nodeY - nodeStyle.margin[ 3 ] ) : ( nodeY + nodeStyle.margin[ 3 ] ) );
if ( nodeY > sY ) connect.getDrawer().carcTo( nodeStyle.margin[ 3 ], nodeX, nodeY );
else connect.getDrawer().carcTo( nodeStyle.margin[ 3 ], nodeX, nodeY, 0, 1 );
connect.stroke( nodeStyle.stroke );
} }
var transsY = Layout.y + node.getRenderContainer().getHeight() / 2;
connect.getDrawer().clear()
.moveTo( ssX, ssY )
.lineTo( ssX, transsY )
.lineTo( Layout.x, transsY );
connect.stroke( nodeStyles.sub.stroke );
} }
//更新收放icon //更新收放icon
if ( nodeType !== "root" ) { if ( nodeType !== "root" && node.getChildren().length !== 0 ) {
if ( !Layout.shicon ) { if ( !Layout.shicon ) {
Layout.shicon = new ShIcon( node ); Layout.shicon = new ShIcon( node );
} }
...@@ -2941,21 +2987,13 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -2941,21 +2987,13 @@ KityMinder.registerModule( "LayoutBottom", function () {
switch ( nodeType ) { switch ( nodeType ) {
case "root": case "root":
case "main": case "main":
case "sub":
if ( highlight ) { if ( highlight ) {
Layout.bgRect.fill( nodeStyle.highlight ); Layout.bgRect.fill( nodeStyle.highlight );
} else { } else {
Layout.bgRect.fill( nodeStyle.fill ); Layout.bgRect.fill( nodeStyle.fill );
} }
break; break;
case "sub":
if ( highlight ) {
Layout.highlightshape.fill( nodeStyle.highlight ).setOpacity( 1 );
node.getTextShape().fill( 'black' );
} else {
Layout.highlightshape.setOpacity( 0 );
node.getTextShape().fill( 'white' );
}
break;
default: default:
break; break;
} }
...@@ -2969,13 +3007,18 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -2969,13 +3007,18 @@ KityMinder.registerModule( "LayoutBottom", function () {
}, false ) ); }, false ) );
updateShapeByCont( node ); updateShapeByCont( node );
var set1 = updateLayoutHorizon( node ); var set = updateLayoutAll( node, node.getParent(), "change" );
var set2 = updateLayoutVertical( node, node.getParent(), "change" );
var set = uSet( set1, set2 );
for ( var i = 0; i < set.length; i++ ) { for ( var i = 0; i < set.length; i++ ) {
translateNode( set[ i ] ); translateNode( set[ i ] );
updateConnectAndshIcon( set[ i ] ); updateConnectAndshIcon( set[ i ] );
} }
if ( node.getType() === "sub" ) {
var set1 = updateLayoutMain();
for ( var j = 0; j < set1.length; j++ ) {
translateNode( set1[ j ] );
updateConnectAndshIcon( set1[ j ] );
}
}
}, },
initStyle: function () { initStyle: function () {
var _root = minder.getRoot(); var _root = minder.getRoot();
...@@ -2991,8 +3034,7 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -2991,8 +3034,7 @@ KityMinder.registerModule( "LayoutBottom", function () {
node: _root node: _root
}, false ) ); }, false ) );
updateShapeByCont( _root ); updateShapeByCont( _root );
updateLayoutHorizon( _root ); updateLayoutAll( _root );
updateLayoutVertical( _root );
translateNode( _root ); translateNode( _root );
var _buffer = [ _root ]; var _buffer = [ _root ];
var _cleanbuffer = []; var _cleanbuffer = [];
...@@ -3013,13 +3055,22 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -3013,13 +3055,22 @@ KityMinder.registerModule( "LayoutBottom", function () {
} }
}, },
appendChildNode: function ( parent, node, sibling ) { appendChildNode: function ( parent, node, sibling ) {
minder.handelNodeInsert( node );
node.clearLayout(); node.clearLayout();
var parentLayout = parent.getLayout();
//设置分支类型 //设置分支类型
if ( parent.getType() === "root" ) { if ( parent.getType() === "root" ) {
node.setType( "main" ); node.setType( "main" );
minder.handelNodeInsert( node );
} else { } else {
node.setType( "sub" ); node.setType( "sub" );
//将节点加入到main分支的subgroup中
parentLayout.subgroup.addShape( node.getRenderContainer() );
node.getLayout().subgroup = parentLayout.subgroup;
}
if ( sibling ) {
parent.insertChild( node, sibling.getIndex() + 1 );
} else {
parent.appendChild( node );
} }
//计算位置等流程 //计算位置等流程
updateBg( node ); updateBg( node );
...@@ -3031,22 +3082,97 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -3031,22 +3082,97 @@ KityMinder.registerModule( "LayoutBottom", function () {
node: node node: node
}, false ) ); }, false ) );
updateShapeByCont( node ); updateShapeByCont( node );
var set2 = updateLayoutHorizon( node, parent, "append" ); var set = updateLayoutAll( node, parent, "append" );
var set1 = updateLayoutVertical( node );
var set = uSet( set1, set2 );
for ( var i = 0; i < set.length; i++ ) { for ( var i = 0; i < set.length; i++ ) {
translateNode( set[ i ] ); translateNode( set[ i ] );
updateConnectAndshIcon( set[ i ] ); updateConnectAndshIcon( set[ i ] );
} }
if ( node.getType() === "sub" ) {
var set1 = updateLayoutMain();
for ( var j = 0; j < set1.length; j++ ) {
translateNode( set1[ j ] );
updateConnectAndshIcon( set1[ j ] );
}
}
}, },
appendSiblingNode: function ( sibling, node ) { appendSiblingNode: function ( sibling, node ) {
var parent = sibling.getParent();
this.appendChildNode( parent, node, sibling );
}, },
removeNode: function ( nodes ) { removeNode: function ( nodes ) {
while ( nodes.length !== 0 ) {
var parent = nodes[ 0 ].getParent();
if ( !parent ) {
nodes.splice( 0, 1 );
return false;
}
var nodeLayout = nodes[ 0 ].getLayout();
parent.removeChild( nodes[ 0 ] );
var set = updateLayoutAll( nodes[ 0 ], parent, "remove" );
for ( var j = 0; j < set.length; j++ ) {
translateNode( set[ j ] );
updateConnectAndshIcon( set[ j ] );
}
var set1 = updateLayoutMain();
for ( var k = 0; k < set1.length; k++ ) {
translateNode( set1[ k ] );
updateConnectAndshIcon( set1[ k ] );
}
var _buffer = [ nodes[ 0 ] ];
while ( _buffer.length !== 0 ) {
_buffer = _buffer.concat( _buffer[ 0 ].getChildren() );
try {
_buffer[ 0 ].getRenderContainer().remove();
var Layout = _buffer[ 0 ].getLayout();
Layout.connect.remove();
Layout.shicon.remove();
} catch ( error ) {
console.log( "isRemoved" );
}
//检测当前节点是否在选中的数组中,如果在的话,从选中数组中去除
var idx = nodes.indexOf( _buffer[ 0 ] );
if ( idx !== -1 ) {
nodes.splice( idx, 1 );
}
_buffer.shift();
}
}
}, },
expandNode: function ( ico ) { expandNode: function ( ico ) {
var isExpand = ico.icon.switchState();
var node = ico.icon._node;
var _buffer = node.getChildren();
var _cleanbuffer = [];
while ( _buffer.length !== 0 ) {
var Layout = _buffer[ 0 ].getLayout();
if ( isExpand ) {
var parent = _buffer[ 0 ].getParent();
Layout.parent = parent;
_cleanbuffer.push( _buffer[ 0 ] );
Layout.connect = null;
Layout.shicon = null;
} else {
_buffer[ 0 ].getRenderContainer().remove();
Layout.connect.remove();
if ( Layout.shicon ) Layout.shicon.remove();
}
_buffer = _buffer.concat( _buffer[ 0 ].getChildren() );
_buffer.shift();
}
if ( isExpand ) {
node.clearChildren();
for ( var j = 0; j < _cleanbuffer.length; j++ ) {
_cleanbuffer[ j ].clearChildren();
minder.appendChildNode( _cleanbuffer[ j ].getLayout().parent, _cleanbuffer[ j ] );
}
}
var set = [];
if ( !isExpand ) set = updateLayoutAll( node, node.getParent(), "contract" );
for ( var i = 0; i < set.length; i++ ) {
translateNode( set[ i ] );
updateConnectAndshIcon( set[ i ] );
}
} }
}; };
this.addLayoutStyle( "bottom", _style ); this.addLayoutStyle( "bottom", _style );
...@@ -3344,7 +3470,7 @@ var MoveToParentCommand = kity.createClass( 'MoveToParentCommand', { ...@@ -3344,7 +3470,7 @@ var MoveToParentCommand = kity.createClass( 'MoveToParentCommand', {
function boxMapper( node ) { function boxMapper( node ) {
return node.getRenderContainer().getRenderBox(); return node.getRenderContainer().getRenderBox( 'top' );
} }
// 对拖动对象的一个替代盒子,控制整个拖放的逻辑,包括: // 对拖动对象的一个替代盒子,控制整个拖放的逻辑,包括:
...@@ -3391,6 +3517,12 @@ var DragBox = kity.createClass( "DragBox", { ...@@ -3391,6 +3517,12 @@ var DragBox = kity.createClass( "DragBox", {
ancestors = [], ancestors = [],
judge; judge;
// 根节点不参与计算
var rootIndex = nodes.indexOf( this._minder.getRoot() );
if ( ~rootIndex ) {
nodes.splice( rootIndex, 1 );
}
// 判断 nodes 列表中是否存在 judge 的祖先 // 判断 nodes 列表中是否存在 judge 的祖先
function hasAncestor( nodes, judge ) { function hasAncestor( nodes, judge ) {
for ( var i = nodes.length - 1; i >= 0; --i ) { for ( var i = nodes.length - 1; i >= 0; --i ) {
...@@ -3449,10 +3581,15 @@ var DragBox = kity.createClass( "DragBox", { ...@@ -3449,10 +3581,15 @@ var DragBox = kity.createClass( "DragBox", {
// 4. 标记已启动 // 4. 标记已启动
_enterDragMode: function () { _enterDragMode: function () {
this._calcDragSources(); this._calcDragSources();
if ( !this._dragSources.length ) {
this._startPosition = null;
return false;
}
this._calcDropTargets(); this._calcDropTargets();
this._drawForDragMode(); this._drawForDragMode();
this._shrink(); this._shrink();
this._dragMode = true; this._dragMode = true;
return true;
}, },
_leaveDragMode: function () { _leaveDragMode: function () {
this.remove(); this.remove();
...@@ -3539,16 +3676,21 @@ var DragBox = kity.createClass( "DragBox", { ...@@ -3539,16 +3676,21 @@ var DragBox = kity.createClass( "DragBox", {
}, },
dragMove: function ( position ) { dragMove: function ( position ) {
// 启动拖放模式需要最小的移动距离
var DRAG_MOVE_THRESHOLD = 10;
if ( !this._startPosition ) return; if ( !this._startPosition ) return;
this._dragPosition = position; this._dragPosition = position;
if ( !this._dragMode ) { if ( !this._dragMode ) {
// 判断拖放模式是否该启动 // 判断拖放模式是否该启动
if ( GM.getDistance( this._dragPosition, this._startPosition ) < 10 ) { if ( GM.getDistance( this._dragPosition, this._startPosition ) < DRAG_MOVE_THRESHOLD ) {
return;
}
if ( !this._enterDragMode() ) {
return; return;
} }
this._enterDragMode();
} }
var movement = kity.Vector.fromPoints( this._startPosition, this._dragPosition ); var movement = kity.Vector.fromPoints( this._startPosition, this._dragPosition );
...@@ -3581,7 +3723,8 @@ KityMinder.registerModule( "DragTree", function () { ...@@ -3581,7 +3723,8 @@ KityMinder.registerModule( "DragTree", function () {
}, },
events: { events: {
mousedown: function ( e ) { mousedown: function ( e ) {
if ( e.getTargetNode() ) { // 单选中根节点也不触发拖拽
if ( e.getTargetNode() && e.getTargetNode() != this.getRoot() ) {
this._dragBox.dragStart( e.getPosition() ); this._dragBox.dragStart( e.getPosition() );
} }
}, },
...@@ -3791,7 +3934,9 @@ KityMinder.registerModule( "Select", function () { ...@@ -3791,7 +3934,9 @@ KityMinder.registerModule( "Select", function () {
startPosition = g.snapToSharp( e.getPosition() ); startPosition = g.snapToSharp( e.getPosition() );
}, },
selectMove: function ( e ) { selectMove: function ( e ) {
if ( minder.isTextEditStatus() ) {
return;
}
if ( !startPosition ) return; if ( !startPosition ) return;
var p1 = startPosition, var p1 = startPosition,
...@@ -3827,7 +3972,7 @@ KityMinder.registerModule( "Select", function () { ...@@ -3827,7 +3972,7 @@ KityMinder.registerModule( "Select", function () {
// 计算选中范围 // 计算选中范围
minder.getRoot().traverse( function ( node ) { minder.getRoot().traverse( function ( node ) {
var renderBox = node.getRenderContainer().getRenderBox(); var renderBox = node.getRenderContainer().getRenderBox( "top" );
if ( g.isBoxIntersect( renderBox, marquee ) ) { if ( g.isBoxIntersect( renderBox, marquee ) ) {
selectedNodes.push( node ); selectedNodes.push( node );
} }
...@@ -3842,7 +3987,7 @@ KityMinder.registerModule( "Select", function () { ...@@ -3842,7 +3987,7 @@ KityMinder.registerModule( "Select", function () {
} }
if ( marqueeMode ) { if ( marqueeMode ) {
marqueeShape.fadeOut( 200, 'ease', 0, function () { marqueeShape.fadeOut( 200, 'ease', 0, function () {
if(marqueeShape.remove) marqueeShape.remove(); if ( marqueeShape.remove ) marqueeShape.remove();
} ); } );
marqueeMode = false; marqueeMode = false;
} }
...@@ -4039,8 +4184,8 @@ KityMinder.registerModule( "HistoryModule", function () { ...@@ -4039,8 +4184,8 @@ KityMinder.registerModule( "HistoryModule", function () {
} ) } )
}, },
addShortcutKeys: { addShortcutKeys: {
"Undo": "ctrl+90", //undo "Undo": "ctrl+z", //undo
"Redo": "ctrl+89" //redo "Redo": "ctrl+y" //redo
}, },
"events": { "events": {
"saveScene": function ( e ) { "saveScene": function ( e ) {
...@@ -4095,6 +4240,12 @@ KityMinder.registerModule( "TextEditModule", function () { ...@@ -4095,6 +4240,12 @@ KityMinder.registerModule( "TextEditModule", function () {
km.isTextEditStatus = function(){
return km.receiver.isTextEditStatus();
};
var selectionByClick = false;
return { return {
//插入光标 //插入光标
"init":function(){ "init":function(){
...@@ -4104,12 +4255,19 @@ KityMinder.registerModule( "TextEditModule", function () { ...@@ -4104,12 +4255,19 @@ KityMinder.registerModule( "TextEditModule", function () {
'beforemousedown':function(e){ 'beforemousedown':function(e){
sel.setHide(); sel.setHide();
var node = e.getTargetNode(); var node = e.getTargetNode();
if(!node){
var selectionShape = e.kityEvent.targetShape;
if(selectionShape && selectionShape.getType() == 'Selection'){
selectionByClick = true;
node = selectionShape.getData('relatedNode');
e.stopPropagationImmediately();
}
}
if(node){ if(node){
var textShape = node.getTextShape(); var textShape = node.getTextShape();
textShape.setStyle('cursor','default'); textShape.setStyle('cursor','default');
if ( this.isSingleSelect() && node.isSelected() && e.kityEvent.targetShape.getType().toLowerCase()== 'text') { if ( this.isSingleSelect() && node.isSelected()) {// && e.kityEvent.targetShape.getType().toLowerCase()== 'text'
sel.collapse(); sel.collapse();
node.getTextShape().setStyle('cursor','text'); node.getTextShape().setStyle('cursor','text');
receiver.setTextEditStatus(true) receiver.setTextEditStatus(true)
...@@ -4123,27 +4281,44 @@ KityMinder.registerModule( "TextEditModule", function () { ...@@ -4123,27 +4281,44 @@ KityMinder.registerModule( "TextEditModule", function () {
.setCurrentIndex(e.getPosition()) .setCurrentIndex(e.getPosition())
.updateSelection() .updateSelection()
.setRange(range); .setRange(range);
sel.setData('relatedNode',node);
mouseDownStatus = true; mouseDownStatus = true;
lastEvtPosition = e.getPosition(); lastEvtPosition = e.getPosition();
if(selectionByClick){
sel.setShow();
selectionByClick = false;
}
} }
} }
}, },
'mouseup':function(e){ 'mouseup':function(e){
if(!sel.collapsed && mouseDownStatus){ if(mouseDownStatus){
if(!sel.collapsed ){
receiver.updateRange(range) receiver.updateRange(range)
}else
sel.setShow()
} }
mouseDownStatus = false; mouseDownStatus = false;
oneTime = 0; oneTime = 0;
}, },
'beforemousemove':function(e){ 'beforemousemove':function(e){
if(mouseDownStatus){ if(mouseDownStatus){
e.stopPropagationImmediately(); e.stopPropagationImmediately();
var offset = e.getPosition(); var offset = e.getPosition();
if(Math.abs(offset.y - lastEvtPosition.y) > 2 && Math.abs(lastEvtPosition.x - offset.x) < 1 ){
sel.setHide();
mouseDownStatus = false;
return;
}
dir = offset.x > lastEvtPosition.x ? 1 : (offset.x < lastEvtPosition.x ? -1 : dir); dir = offset.x > lastEvtPosition.x ? 1 : (offset.x < lastEvtPosition.x ? -1 : dir);
receiver.updateSelectionByMousePosition(offset,dir) receiver.updateSelectionByMousePosition(offset,dir)
.updateSelectionShow(dir); .updateSelectionShow(dir);
sel.stroke('none',0);
lastEvtPosition = e.getPosition(); lastEvtPosition = e.getPosition();
} }
}, },
'dblclick':function(e){ 'dblclick':function(e){
...@@ -4154,8 +4329,8 @@ KityMinder.registerModule( "TextEditModule", function () { ...@@ -4154,8 +4329,8 @@ KityMinder.registerModule( "TextEditModule", function () {
sel.setStartOffset(0); sel.setStartOffset(0);
sel.setEndOffset(text.getContent().length); sel.setEndOffset(text.getContent().length);
sel.setShow(); sel.setShow();
receiver.updateSelectionShow(1) receiver.setContainerTxt(text.getContent()).updateSelectionShow(1)
.updateRange(range); .updateRange(range).setTextEditStatus(true)
} }
}, },
...@@ -4198,7 +4373,7 @@ KityMinder.registerModule( "TextEditModule", function () { ...@@ -4198,7 +4373,7 @@ KityMinder.registerModule( "TextEditModule", function () {
receiver.updateSelectionShow(1) receiver.updateSelectionShow(1)
.updateRange(range); .updateRange(range);
return;
} }
...@@ -4211,10 +4386,11 @@ KityMinder.registerModule( "TextEditModule", function () { ...@@ -4211,10 +4386,11 @@ KityMinder.registerModule( "TextEditModule", function () {
}else{ }else{
receiver.updateSelectionShow(1) receiver.updateSelectionShow(1)
} }
return;
} }
receiver.clear().setTextEditStatus(false);
}, },
'selectionclear':function(){ 'selectionclear':function(){
receiver.setTextEditStatus(false).clear() receiver.setTextEditStatus(false).clear()
...@@ -4241,7 +4417,12 @@ Minder.Range = kity.createClass('Range',{ ...@@ -4241,7 +4417,12 @@ Minder.Range = kity.createClass('Range',{
return this; return this;
}, },
setStart:function(node,index){ setStart:function(node,index){
try{
this.nativeRange.setStart(node,index); this.nativeRange.setStart(node,index);
}catch(e){
console.log(e)
}
return this; return this;
}, },
setEnd:function(node,index){ setEnd:function(node,index){
...@@ -4490,16 +4671,17 @@ Minder.Receiver = kity.createClass('Receiver',{ ...@@ -4490,16 +4671,17 @@ Minder.Receiver = kity.createClass('Receiver',{
return false; return false;
} }
if(offset.x >= v.x && offset.x <= v.x + v.width){ if(offset.x >= v.x && offset.x <= v.x + v.width){
if(me.index == i){ if(me.index == i){
if(i == 0){ if(i == 0){
me.selection.setStartOffset(i) me.selection.setStartOffset(i)
} }
me.selection.setEndOffset(i + (dir == 1 ? 1 : 0)) me.selection.setEndOffset(i + (dir == 1 ? 1 : 0))
}else if(i > me.index){ }else if(i > me.index){
me.selection.setStartOffset(me.index);
me.selection.setEndOffset(i + (dir == 1 ? 1 : 0)) me.selection.setEndOffset(i + (dir == 1 ? 1 : 0))
}else{ }else{
me.selection.setStartOffset(i + (dir == 1 ? 1 : 0)) me.selection.setStartOffset(i + (dir == 1 ? 1 : 0));
me.selection.setEndOffset(me.index)
} }
return false; return false;
...@@ -4513,7 +4695,7 @@ Minder.Receiver = kity.createClass('Receiver',{ ...@@ -4513,7 +4695,7 @@ Minder.Receiver = kity.createClass('Receiver',{
width = 0 ; width = 0 ;
if(this.selection.collapsed){ if(this.selection.collapsed){
this.selection.updateShow(startOffset,0); this.selection.updateShow(startOffset||this.textData[this.textData.length-1],0);
return this; return this;
} }
if(!endOffset){ if(!endOffset){
...@@ -4536,6 +4718,10 @@ Minder.Receiver = kity.createClass('Receiver',{ ...@@ -4536,6 +4718,10 @@ Minder.Receiver = kity.createClass('Receiver',{
setIndex:function(index){ setIndex:function(index){
this.index = index; this.index = index;
return this return this
},
setContainerTxt:function(txt){
this.container.textContent = txt;
return this;
} }
}); });
...@@ -4546,18 +4732,20 @@ Minder.Selection = kity.createClass( 'Selection', { ...@@ -4546,18 +4732,20 @@ Minder.Selection = kity.createClass( 'Selection', {
this.callBase(); this.callBase();
this.height = height || 20; this.height = height || 20;
this.stroke( color || 'blue', width || 1 ); this.stroke( color || 'rgb(27,171,255)', width || 1 );
this.width = 1; this.width = 0;
this.fill('#99C8FF'); this.fill('rgb(27,171,255)');
this.setHide(); this.setHide();
this.timer = null; this.timer = null;
this.collapsed = true; this.collapsed = true;
this.startOffset = this.endOffset = 0; this.startOffset = this.endOffset = 0;
this.setOpacity(0.5) this.setOpacity(0.5);
this.setStyle('cursor','text');
}, },
collapse : function(toEnd){ collapse : function(toEnd){
this.stroke( 'blue', 1 ); this.stroke( 'rgb(27,171,255)', 1 );
this.setOpacity(1);
this.width = 1; this.width = 1;
this.collapsed = true; this.collapsed = true;
if(toEnd){ if(toEnd){
...@@ -4578,7 +4766,8 @@ Minder.Selection = kity.createClass( 'Selection', { ...@@ -4578,7 +4766,8 @@ Minder.Selection = kity.createClass( 'Selection', {
return this; return this;
} }
this.collapsed = false; this.collapsed = false;
this.stroke('none'); this.stroke('none',0);
this.setOpacity(0.5);
return this; return this;
}, },
setEndOffset:function(offset){ setEndOffset:function(offset){
...@@ -4592,10 +4781,14 @@ Minder.Selection = kity.createClass( 'Selection', { ...@@ -4592,10 +4781,14 @@ Minder.Selection = kity.createClass( 'Selection', {
return this; return this;
} }
this.collapsed = false; this.collapsed = false;
this.stroke('none'); this.stroke('none',0);
this.setOpacity(0.5);
return this; return this;
}, },
updateShow : function(offset,width){ updateShow : function(offset,width){
if(width){
this.setShowHold();
}
this.setPosition(offset).setWidth(width); this.setPosition(offset).setWidth(width);
return this; return this;
}, },
...@@ -4605,7 +4798,7 @@ Minder.Selection = kity.createClass( 'Selection', { ...@@ -4605,7 +4798,7 @@ Minder.Selection = kity.createClass( 'Selection', {
this.y = offset.y; this.y = offset.y;
} catch ( e ) { } catch ( e ) {
console.log(e) debugger
} }
return this.update(); return this.update();
...@@ -4728,8 +4921,8 @@ KityMinder.registerModule( "basestylemodule", function () { ...@@ -4728,8 +4921,8 @@ KityMinder.registerModule( "basestylemodule", function () {
} ) } )
}, },
addShortcutKeys: { addShortcutKeys: {
"bold": "ctrl+66", //bold "bold": "ctrl+b", //bold
"italic": "ctrl+73" //italic "italic": "ctrl+i" //italic
}, },
"events": { "events": {
"beforeRenderNode": function ( e ) { "beforeRenderNode": function ( e ) {
...@@ -4909,7 +5102,7 @@ KityMinder.registerModule( 'Zoom', function () { ...@@ -4909,7 +5102,7 @@ KityMinder.registerModule( 'Zoom', function () {
'zoom-out': ZoomOutCommand 'zoom-out': ZoomOutCommand
}, },
addShortcutKeys: { addShortcutKeys: {
"zoom-in": "+", //= "zoom-in": "=", //=
"zoom-out": "-" //- "zoom-out": "-" //-
}, },
events: { events: {
...@@ -5755,7 +5948,7 @@ KM.ui.define('colorpicker', { ...@@ -5755,7 +5948,7 @@ KM.ui.define('colorpicker', {
"<%if(autoRecord) {%>" + "<%if(autoRecord) {%>" +
"<%for( var i=0, len = recordStack.length; i<len; i++ ) {%>" + "<%for( var i=0, len = recordStack.length; i<len; i++ ) {%>" +
"<%var index = recordStack[i];%>" + "<%var index = recordStack[i];%>" +
"<li class=\"<%=itemClassName%><%if( selected == index ) {%> kmui-combobox-checked<%}%>\" data-item-index=\"<%=index%>\" unselectable=\"on\" onmousedown=\"return false\">" + "<li class=\"<%=itemClassName%><%if( selected == index ) {%> kmui-combobox-checked<%}%><%if( disabled[ index ] === true ) {%> kmui-combobox-item-disabled<%}%>\" data-item-index=\"<%=index%>\" unselectable=\"on\" onmousedown=\"return false\">" +
"<span class=\"kmui-combobox-icon\" unselectable=\"on\" onmousedown=\"return false\"></span>" + "<span class=\"kmui-combobox-icon\" unselectable=\"on\" onmousedown=\"return false\"></span>" +
"<label class=\"<%=labelClassName%>\" style=\"<%=itemStyles[ index ]%>\" unselectable=\"on\" onmousedown=\"return false\"><%=items[index]%></label>" + "<label class=\"<%=labelClassName%>\" style=\"<%=itemStyles[ index ]%>\" unselectable=\"on\" onmousedown=\"return false\"><%=items[index]%></label>" +
"</li>" + "</li>" +
...@@ -5765,7 +5958,7 @@ KM.ui.define('colorpicker', { ...@@ -5765,7 +5958,7 @@ KM.ui.define('colorpicker', {
"<%}%>" + "<%}%>" +
"<%}%>" + "<%}%>" +
"<%for( var i=0, label; label = items[i]; i++ ) {%>" + "<%for( var i=0, label; label = items[i]; i++ ) {%>" +
"<li class=\"<%=itemClassName%><%if( selected == i ) {%> kmui-combobox-checked<%}%> kmui-combobox-item-<%=i%>\" data-item-index=\"<%=i%>\" unselectable=\"on\" onmousedown=\"return false\">" + "<li class=\"<%=itemClassName%><%if( selected == i ) {%> kmui-combobox-checked<%}%> kmui-combobox-item-<%=i%><%if( disabled[ i ] === true ) {%> kmui-combobox-item-disabled<%}%>\" data-item-index=\"<%=i%>\" unselectable=\"on\" onmousedown=\"return false\">" +
"<span class=\"kmui-combobox-icon\" unselectable=\"on\" onmousedown=\"return false\"></span>" + "<span class=\"kmui-combobox-icon\" unselectable=\"on\" onmousedown=\"return false\"></span>" +
"<label class=\"<%=labelClassName%>\" style=\"<%=itemStyles[ i ]%>\" unselectable=\"on\" onmousedown=\"return false\"><%=label%></label>" + "<label class=\"<%=labelClassName%>\" style=\"<%=itemStyles[ i ]%>\" unselectable=\"on\" onmousedown=\"return false\"><%=label%></label>" +
"</li>" + "</li>" +
...@@ -5780,10 +5973,13 @@ KM.ui.define('colorpicker', { ...@@ -5780,10 +5973,13 @@ KM.ui.define('colorpicker', {
value: [], value: [],
comboboxName: '', comboboxName: '',
selected: '', selected: '',
//初始禁用状态
disabled: {},
//自动记录 //自动记录
autoRecord: true, autoRecord: true,
//最多记录条数 //最多记录条数
recordCount: 5 recordCount: 5,
enabledRecord:true
}, },
init: function( options ){ init: function( options ){
...@@ -5821,6 +6017,7 @@ KM.ui.define('colorpicker', { ...@@ -5821,6 +6017,7 @@ KM.ui.define('colorpicker', {
initSelectItem: function(){ initSelectItem: function(){
var me = this, var me = this,
options = me.data( "options" ),
labelClass = "."+labelClassName; labelClass = "."+labelClassName;
me.root().delegate('.' + itemClassName, 'click', function(){ me.root().delegate('.' + itemClassName, 'click', function(){
...@@ -5828,6 +6025,10 @@ KM.ui.define('colorpicker', { ...@@ -5828,6 +6025,10 @@ KM.ui.define('colorpicker', {
var $li = $(this), var $li = $(this),
index = $li.attr('data-item-index'); index = $li.attr('data-item-index');
if ( options.disabled[ index ] ) {
return false;
}
me.trigger('comboboxselect', { me.trigger('comboboxselect', {
index: index, index: index,
label: $li.find(labelClass).text(), label: $li.find(labelClass).text(),
...@@ -5860,11 +6061,18 @@ KM.ui.define('colorpicker', { ...@@ -5860,11 +6061,18 @@ KM.ui.define('colorpicker', {
*/ */
select: function( index ){ select: function( index ){
var itemCount = this.data('options').itemCount,
items = this.data('options').autowidthitem; var options = this.data( 'options' ),
itemCount = options.itemCount,
items = options.autowidthitem;
if ( items && !items.length ) { if ( items && !items.length ) {
items = this.data('options').items; items = options.items;
}
// 禁用
if ( options.disabled[ index ] ) {
return null;
} }
if( itemCount == 0 ) { if( itemCount == 0 ) {
...@@ -5883,6 +6091,7 @@ KM.ui.define('colorpicker', { ...@@ -5883,6 +6091,7 @@ KM.ui.define('colorpicker', {
this.trigger( 'changebefore', items[ index ] ); this.trigger( 'changebefore', items[ index ] );
this._update( index ); this._update( index );
this.trigger( 'changeafter', items[ index ] ); this.trigger( 'changeafter', items[ index ] );
...@@ -5912,6 +6121,65 @@ KM.ui.define('colorpicker', { ...@@ -5912,6 +6121,65 @@ KM.ui.define('colorpicker', {
} ); } );
}, },
getItems: function () {
return this.data( "options" ).items;
},
traverseItems:function(fn){
var values = this.data('options').value;
var labels = this.data('options').items;
$.each(labels,function(i,label){
fn(label,values[i])
});
return this;
},
getItemMapping: function () {
return this.data( "options" ).itemMapping;
},
disableItemByIndex: function ( index ) {
var options = this.data( "options" );
options.disabled[ index ] = true;
this._repaint();
},
disableItemByLabel: function ( label ) {
var itemMapping = this.data('options').itemMapping,
index = itemMapping[ label ];
if ( typeof index === "number" ) {
return this.disableItemByIndex( index );
}
return false;
},
enableItemByIndex: function ( index ) {
var options = this.data( "options" );
delete options.disabled[ index ];
this._repaint();
},
enableItemByLabel: function ( label ) {
var itemMapping = this.data('options').itemMapping,
index = itemMapping[ label ];
if ( typeof index === "number" ) {
return this.enableItemByIndex( index );
}
return false;
},
/** /**
* 转换记录栈 * 转换记录栈
*/ */
...@@ -5990,9 +6258,9 @@ KM.ui.define('colorpicker', { ...@@ -5990,9 +6258,9 @@ KM.ui.define('colorpicker', {
_update: function ( index ) { _update: function ( index ) {
var options = this.data("options"), var options = this.data("options"),
newStack = [], newStack = [];
newChilds = null;
if(this.data('options').enabledRecord){
$.each( options.recordStack, function( i, item ){ $.each( options.recordStack, function( i, item ){
if( item != index ) { if( item != index ) {
...@@ -6009,15 +6277,24 @@ KM.ui.define('colorpicker', { ...@@ -6009,15 +6277,24 @@ KM.ui.define('colorpicker', {
} }
options.recordStack = newStack; options.recordStack = newStack;
}
options.selected = index; options.selected = index;
newChilds = $( $.parseTmpl( this.tpl, options ) ); this._repaint();
newStack = null;
},
_repaint: function () {
var newChilds = $( $.parseTmpl( this.tpl, this.data("options") ) );
//重新渲染 //重新渲染
this.root().html( newChilds.html() ); this.root().html( newChilds.html() );
newChilds = null; newChilds = null;
newStack = null;
} }
}; };
...@@ -6748,7 +7025,7 @@ KM.registerToolbarUI( 'bold italic redo undo', ...@@ -6748,7 +7025,7 @@ KM.registerToolbarUI( 'bold italic redo undo',
} }
); );
KM.registerToolbarUI( 'layoutstyle fontfamily fontsize', function ( name ) { KM.registerToolbarUI( 'fontfamily fontsize', function ( name ) {
var me = this, var me = this,
label = me.getLang( 'tooltips.' + name ), label = me.getLang( 'tooltips.' + name ),
...@@ -6769,9 +7046,7 @@ KM.registerToolbarUI( 'layoutstyle fontfamily fontsize', function ( name ) { ...@@ -6769,9 +7046,7 @@ KM.registerToolbarUI( 'layoutstyle fontfamily fontsize', function ( name ) {
} }
switch ( name ) { switch ( name ) {
case 'layoutstyle':
options = transForLayoutstyle( options );
break;
case 'fontfamily': case 'fontfamily':
options = transForFontfamily( options ); options = transForFontfamily( options );
...@@ -6812,24 +7087,6 @@ KM.registerToolbarUI( 'layoutstyle fontfamily fontsize', function ( name ) { ...@@ -6812,24 +7087,6 @@ KM.registerToolbarUI( 'layoutstyle fontfamily fontsize', function ( name ) {
return comboboxWidget.button().addClass( 'kmui-combobox' ); return comboboxWidget.button().addClass( 'kmui-combobox' );
function transForLayoutstyle( options ) {
var tempItems = [];
utils.each( options.items, function ( k, v ) {
options.value.push( k );
tempItems.push( k );
options.autowidthitem.push( $.wordCountAdaptive( tempItems[ tempItems.length - 1 ] ) );
} );
options.items = tempItems;
return options;
}
//字体参数转换 //字体参数转换
function transForFontfamily( options ) { function transForFontfamily( options ) {
...@@ -6954,7 +7211,8 @@ KM.registerToolbarUI( 'saveto', function ( name ) { ...@@ -6954,7 +7211,8 @@ KM.registerToolbarUI( 'saveto', function ( name ) {
items: [], items: [],
itemStyles: [], itemStyles: [],
value: [], value: [],
autowidthitem: [] autowidthitem: [],
enabledRecord:false
}, },
$combox = null, $combox = null,
comboboxWidget = null; comboboxWidget = null;
...@@ -6975,6 +7233,53 @@ KM.registerToolbarUI( 'saveto', function ( name ) { ...@@ -6975,6 +7233,53 @@ KM.registerToolbarUI( 'saveto', function ( name ) {
comboboxWidget = $combox.kmui(); comboboxWidget = $combox.kmui();
comboboxWidget.on( 'comboboxselect', function ( evt, res ) { comboboxWidget.on( 'comboboxselect', function ( evt, res ) {
if ( res.value === "png" ) {
var svghtml = $( "#kityminder .kmui-editor-body" ).html();
var rootBox = me.getRoot().getRenderContainer().getRenderBox();
var svg = $( svghtml ).attr( {
width: rootBox.x + me.getRenderContainer().getWidth() + 20,
height: rootBox.y + me.getRenderContainer().getHeight() + 20,
viewBox: null
} );
var div = $( "<div></div>" ).append( svg );
svghtml = div.html();
var canvas = $( '<canvas style="border:2px solid black;" width="' + svg.attr( "width" ) + '" height="' + svg.attr( "height" ) + '"></canvas>' );
var ctx = canvas[ 0 ].getContext( "2d" );
var DOMURL = self.URL || self.webkitURL || self;
var img = new Image();
var svg = new Blob( [ svghtml ], {
type: "image/svg+xml;charset=utf-8"
} );
var url = DOMURL.createObjectURL( svg );
img.onload = function () {
ctx.drawImage( img, 0, 0 );
DOMURL.revokeObjectURL( url );
var type = 'png';
var imgData = canvas[ 0 ].toDataURL( type );
var _fixType = function ( type ) {
type = type.toLowerCase().replace( /jpg/i, 'jpeg' );
var r = type.match( /png|jpeg|bmp|gif/ )[ 0 ];
return 'image/' + r;
};
imgData = imgData.replace( _fixType( type ), 'image/octet-stream' );
var saveFile = function ( data, filename ) {
var save_link = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'a' );
save_link.href = data;
save_link.download = filename;
var event = document.createEvent( 'MouseEvents' );
event.initMouseEvent( 'click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null );
save_link.dispatchEvent( event );
};
// 下载后的问题名
var filename = 'kityminder_' + ( new Date() ).getTime() + '.' + type;
// download
saveFile( imgData, filename );
};
img.src = url;
return "png";
}
var data = me.exportData( res.value ); var data = me.exportData( res.value );
var p = KityMinder.findProtocal( res.value ); var p = KityMinder.findProtocal( res.value );
var a = downloadLink; var a = downloadLink;
...@@ -7085,6 +7390,121 @@ KM.registerUI( 'tooltips', ...@@ -7085,6 +7390,121 @@ KM.registerUI( 'tooltips',
} }
); );
KM.registerToolbarUI( 'switchlayout', function ( name ) {
var me = this,
label = me.getLang( 'tooltips.' + name ),
options = {
label: label,
title: label,
comboboxName: name,
items: me.getLayoutStyleItems() || [],
itemStyles: [],
value: me.getLayoutStyleItems(),
autowidthitem: [],
enabledRecord:false
},
$combox = null;
if ( options.items.length == 0 ) {
return null;
}
//实例化
$combox = $.kmuibuttoncombobox( options ).css( 'zIndex', me.getOptions( 'zIndex' ) + 1 );
comboboxWidget = $combox.kmui();
comboboxWidget.on( 'comboboxselect', function ( evt, res ) {
me.execCommand( name, res.value );
} ).on( "beforeshow", function () {
if ( $combox.parent().length === 0 ) {
$combox.appendTo( me.$container.find( '.kmui-dialog-container' ) );
}
} );
//状态反射
me.on( 'interactchange', function () {
var state = this.queryCommandState( name ),
value = this.queryCommandValue( name );
//设置按钮状态
comboboxWidget.button().kmui().disabled( state == -1 ).active( state == 1 );
if ( value ) {
//设置label
value = value.replace( /['"]/g, '' ).toLowerCase().split( /['|"]?\s*,\s*[\1]?/ );
comboboxWidget.selectItemByLabel( value );
}
} );
return comboboxWidget.button().addClass( 'kmui-combobox' );
} );
KM.registerToolbarUI( 'node', function ( name ) {
var shortcutKeys = {
"appendsiblingnode": "enter",
"appendchildnode": "tab",
"removenode": "del|backspace"
};
var me = this,
msg = me.getLang( 'node' ),
label = me.getLang( 'tooltips.' + name ),
options = {
label: label,
title: label,
comboboxName: name,
items: me.getOptions( name ) || [],
itemStyles: [],
value: [],
autowidthitem: [],
enabledRecord: false
},
$combox = null;
if ( options.items.length == 0 ) {
return null;
}
//实例化
$combox = $.kmuibuttoncombobox( transForInserttopic( options ) ).css( 'zIndex', me.getOptions( 'zIndex' ) + 1 );
comboboxWidget = $combox.kmui();
comboboxWidget.on( 'comboboxselect', function ( evt, res ) {
me.execCommand( res.value, new MinderNode( me.getLang().topic ) );
} ).on( "beforeshow", function () {
if ( $combox.parent().length === 0 ) {
$combox.appendTo( me.$container.find( '.kmui-dialog-container' ) );
}
var combox = $combox.kmui();
combox.traverseItems( function ( label, value ) {
if ( me.queryCommandState( value ) == -1 ) {
combox.disableItemByLabel( label )
} else {
combox.enableItemByLabel( label )
}
} )
} );
return comboboxWidget.button().addClass( 'kmui-combobox' );
function transForInserttopic( options ) {
var tempItems = [];
utils.each( options.items, function ( k, v ) {
options.value.push( v );
tempItems.push( ( msg[ k ] || k ) + '(' + shortcutKeys[ v ].toUpperCase() + ')' );
options.autowidthitem.push( $.wordCountAdaptive( tempItems[ tempItems.length - 1 ] ) );
} );
options.items = tempItems;
return options;
}
} );
KityMinder.registerProtocal( "plain", function () { KityMinder.registerProtocal( "plain", function () {
var LINE_ENDING = '\n', var LINE_ENDING = '\n',
TAB_CHAR = '\t'; TAB_CHAR = '\t';
...@@ -7211,3 +7631,106 @@ KityMinder.registerProtocal( 'json', function () { ...@@ -7211,3 +7631,106 @@ KityMinder.registerProtocal( 'json', function () {
}; };
} ); } );
KityMinder.registerProtocal( "png", function () {
var LINE_ENDING = '\n',
TAB_CHAR = '\t';
function repeat( s, n ) {
var result = "";
while ( n-- ) result += s;
return result;
}
function encode( json, level ) {
var local = "";
level = level || 0;
local += repeat( TAB_CHAR, level );
local += json.data.text + LINE_ENDING;
if ( json.children ) {
json.children.forEach( function ( child ) {
local += encode( child, level + 1 );
} );
}
return local;
}
function isEmpty( line ) {
return !/\S/.test( line );
}
function getLevel( line ) {
var level = 0;
while ( line.charAt( level ) === TAB_CHAR ) level++;
return level;
}
function getNode( line ) {
return {
data: {
text: line.replace( new RegExp( '^' + TAB_CHAR + '*' ), '' )
}
};
}
function decode( local ) {
var json,
parentMap = {},
lines = local.split( LINE_ENDING ),
line, level, node;
function addChild( parent, child ) {
var children = parent.children || ( parent.children = [] );
children.push( child );
}
for ( var i = 0; i < lines.length; i++ ) {
line = lines[ i ];
if ( isEmpty( line ) ) continue;
level = getLevel( line );
node = getNode( line );
if ( level === 0 ) {
if ( json ) {
throw new Error( 'Invalid local format' );
}
json = node;
} else {
if ( !parentMap[ level - 1 ] ) {
throw new Error( 'Invalid local format' );
}
addChild( parentMap[ level - 1 ], node );
}
parentMap[ level ] = node;
}
return json;
}
var lastTry, lastResult;
function recognize( local ) {
if ( !Utils.isString( local ) ) return false;
lastTry = local;
try {
lastResult = decode( local );
} catch ( e ) {
lastResult = null;
}
return !!lastResult;
}
return {
fileDescription: 'png',
fileExtension: '.png',
encode: function ( json ) {
return encode( json, 0 );
},
decode: function ( local ) {
if ( lastTry == local && lastResult ) {
return lastResult;
}
return decode( local );
},
recognize: recognize,
recognizePriority: -1
};
} );
...@@ -62,8 +62,11 @@ $dependency = Array( ...@@ -62,8 +62,11 @@ $dependency = Array(
,'src/adapter/view.js' ,'src/adapter/view.js'
,'src/adapter/dialog.js' ,'src/adapter/dialog.js'
,'src/adapter/tooltips.js' ,'src/adapter/tooltips.js'
,'src/adapter/layout.js'
,'src/adapter/node.js'
,'src/protocal/plain.js' ,'src/protocal/plain.js'
,'src/protocal/json.js' ,'src/protocal/json.js'
,'src/protocal/png.js'
); );
$content = ""; $content = "";
......
Subproject commit a9630e638b29633f62cdc2df239bc702118b231a Subproject commit 7c0498012df602619a38e6b88785a486cd92396d
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<scenario xmlns="http://www.omnigroup.com/namespace/OmniPlan/v2" id="mFlQ8Rl4Gch">
<start-date>2014-02-11T00:00:00.000Z</start-date>
<prototype-task>
<task id="t4294967294">
<title>Task 1</title>
<effort>28800</effort>
</task>
</prototype-task>
<prototype-task>
<task id="t4294967293">
<title>Milestone 1</title>
<type>milestone</type>
</task>
</prototype-task>
<prototype-task>
<task id="t4294967292">
<title>Group 1</title>
<type>group</type>
</task>
</prototype-task>
<prototype-resource>
<resource id="r4294967294">
<name>Resource 1</name>
<type>Staff</type>
</resource>
</prototype-resource>
<prototype-resource>
<resource id="r4294967293">
<name>Equipment 1</name>
<type>Equipment</type>
</resource>
</prototype-resource>
<prototype-resource>
<resource id="r4294967292">
<name>Material 1</name>
<type>Material</type>
<units-available>0</units-available>
<efficiency>0</efficiency>
</resource>
</prototype-resource>
<prototype-resource>
<resource id="r4294967291">
<name>Group 1</name>
<type>Group</type>
</resource>
</prototype-resource>
<top-resource idref="r-1"/>
<resource id="r-1">
<type>Group</type>
<child-resource idref="r1"/>
<child-resource idref="r2"/>
<child-resource idref="r3"/>
<child-resource idref="r4"/>
</resource>
<resource id="r1">
<name>Resource 1</name>
<type>Staff</type>
</resource>
<resource id="r2">
<name>家鸣</name>
<type>Staff</type>
</resource>
<resource id="r3">
<name></name>
<type>Staff</type>
</resource>
<resource id="r4">
<name></name>
<type>Staff</type>
</resource>
<top-task idref="t-1"/>
<task id="t-1">
<type>group</type>
<child-task idref="t1"/>
<child-task idref="t2"/>
<child-task idref="t3"/>
<child-task idref="t4"/>
<child-task idref="t6"/>
<child-task idref="t5"/>
<child-task idref="t7"/>
<child-task idref="t8"/>
</task>
<task id="t1">
<title>数据导入导出</title>
<effort>28800</effort>
<max-estimate>115200</max-estimate>
<effort-done>28800</effort-done>
<start-constraint-date>2014-02-12T00:00:00.000Z</start-constraint-date>
<style>
<value key="font-fill">
<color r="0.299775" g="0.436444" b="1"/>
</value>
</style>
<assignment idref="r2"/>
<start-no-earlier-than>2014-02-12T00:00:00.000Z</start-no-earlier-than>
</task>
<task id="t2">
<title>undo/redo</title>
<effort>57600</effort>
<min-estimate>28800</min-estimate>
<max-estimate>102600</max-estimate>
<effort-done>57600</effort-done>
<start-constraint-date>2014-02-12T00:00:00.000Z</start-constraint-date>
<style>
<value key="font-fill">
<color r="0.299775" g="0.436444" b="1"/>
</value>
</style>
<assignment idref="r3"/>
<assignment idref="r4"/>
<start-no-earlier-than>2014-02-12T00:00:00.000Z</start-no-earlier-than>
</task>
<task id="t3">
<title>layout</title>
<effort>27900</effort>
<min-estimate>27000</min-estimate>
<max-estimate>28800</max-estimate>
<effort-done>27900</effort-done>
<start-constraint-date>2014-02-11T00:15:00.000Z</start-constraint-date>
<style>
<value key="font-fill">
<color r="0.299775" g="0.436444" b="1"/>
</value>
</style>
<assignment idref="r3"/>
<start-no-earlier-than>2014-02-11T00:15:00.000Z</start-no-earlier-than>
</task>
<task id="t4">
<title>拖放,改变子树</title>
<effort>57600</effort>
<min-estimate>28800</min-estimate>
<start-constraint-date>2014-02-13T00:00:00.000Z</start-constraint-date>
<assignment idref="r2"/>
<start-no-earlier-than>2014-02-13T00:00:00.000Z</start-no-earlier-than>
</task>
<task id="t5">
<title>添加icon</title>
<effort>86400</effort>
<min-estimate>28800</min-estimate>
<start-constraint-date>2014-02-13T00:00:00.000Z</start-constraint-date>
<assignment idref="r3"/>
<start-no-earlier-than>2014-02-13T00:00:00.000Z</start-no-earlier-than>
</task>
<task id="t6">
<title>ui美化</title>
<effort>55800</effort>
<min-estimate>28800</min-estimate>
<max-estimate>57600</max-estimate>
<start-constraint-date>2014-02-17T00:00:00.000Z</start-constraint-date>
<assignment idref="r2"/>
<assignment idref="r3"/>
<start-no-earlier-than>2014-02-17T00:00:00.000Z</start-no-earlier-than>
</task>
<task id="t7">
<title>官网</title>
<effort>115200</effort>
<min-estimate>28800</min-estimate>
<start-constraint-date>2014-02-18T00:00:00.000Z</start-constraint-date>
<assignment idref="r2"/>
<assignment idref="r3"/>
<start-no-earlier-than>2014-02-18T00:00:00.000Z</start-no-earlier-than>
</task>
<task id="t8">
<title>提测 </title>
<type>milestone</type>
<completion-percentage>1</completion-percentage>
<start-constraint-date>2014-02-20T00:45:00.000Z</start-constraint-date>
<start-no-earlier-than>2014-02-20T00:45:00.000Z</start-no-earlier-than>
</task>
<critical-path root="-1" enabled="false" resources="false">
<color r="1" g="0.5" b="0.5"/>
</critical-path>
</scenario>
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<omniplan xmlns="http://www.omnigroup.com/namespace/OmniPlan/v2">
<window x="1923" y="4" w="1920" h="1054">
<editing-scenario>mFlQ8Rl4Gch</editing-scenario>
<view>task</view>
<change-tracking/>
<draw-folded/>
<status-display>basic</status-display>
<task-view>
<split-view-divider-position>306</split-view-divider-position>
<outline x="0" y="0" w="306" h="935">
<column name="Violations" width="20"/>
<column name="Notes" width="20"/>
<column name="Title" width="191"/>
<column name="Effort" width="70"/>
<selected-items-at-filter-time idrefs="t9 t4 t7 t2 t5 t8 t3 t6"/>
</outline>
<gantt-view x="-26" y="0" w="1598" h="935">
<view-mode>actual</view-mode>
<dependency-lines/>
<constraints/>
<show-project-end/>
<task-bar-label task-type="group" position="left">
<key/>
</task-bar-label>
<task-bar-label task-type="group" position="center">
<key/>
</task-bar-label>
<task-bar-label task-type="group" position="right">
<key>Assigned</key>
</task-bar-label>
<task-bar-label task-type="milestone" position="left">
<key/>
</task-bar-label>
<task-bar-label task-type="milestone" position="center">
<key/>
</task-bar-label>
<task-bar-label task-type="milestone" position="right">
<key>Assigned</key>
</task-bar-label>
<task-bar-label task-type="task" position="left">
<key/>
</task-bar-label>
<task-bar-label task-type="task" position="center">
<key/>
</task-bar-label>
<task-bar-label task-type="task" position="right">
<key>Assigned</key>
</task-bar-label>
<scale scale-name="Automatic" full-day-width="300">
<selected/>
</scale>
<scale scale-name="Day" full-day-width="1215"/>
<scale scale-name="Hour" full-day-width="65880"/>
<scale scale-name="Minute" full-day-width="64800"/>
<scale scale-name="Month" full-day-width="34.5"/>
<scale scale-name="Quarter" full-day-width="9.6"/>
<scale scale-name="Week" full-day-width="162"/>
<scale scale-name="Year" full-day-width="2.3625"/>
</gantt-view>
</task-view>
<resource-view>
<split-view-divider-position>306</split-view-divider-position>
<outline x="0" y="0" w="291" h="935">
<column name="IM" width="20"/>
<column name="Notes" width="20"/>
<column name="Type" width="49"/>
<column name="Resource" width="135"/>
<column name="#" width="75"/>
</outline>
<timeline x="-65" y="0" w="1570" h="935">
<show-project-end/>
<task-bar-label task-type="group" position="left">
<key>Title</key>
</task-bar-label>
<task-bar-label task-type="group" position="center">
<key/>
</task-bar-label>
<task-bar-label task-type="group" position="right">
<key/>
</task-bar-label>
<task-bar-label task-type="milestone" position="left">
<key>Title</key>
</task-bar-label>
<task-bar-label task-type="milestone" position="center">
<key/>
</task-bar-label>
<task-bar-label task-type="milestone" position="right">
<key>Assigned</key>
</task-bar-label>
<task-bar-label task-type="task" position="left">
<key>Title</key>
</task-bar-label>
<task-bar-label task-type="task" position="center">
<key/>
</task-bar-label>
<task-bar-label task-type="task" position="right">
<key/>
</task-bar-label>
<scale scale-name="Automatic" full-day-width="300">
<selected/>
</scale>
<scale scale-name="Day" full-day-width="1215"/>
<scale scale-name="Hour" full-day-width="65880"/>
<scale scale-name="Minute" full-day-width="64800"/>
<scale scale-name="Month" full-day-width="34.5"/>
<scale scale-name="Quarter" full-day-width="9.6"/>
<scale scale-name="Week" full-day-width="162"/>
<scale scale-name="Year" full-day-width="2.3625"/>
</timeline>
</resource-view>
<calendar>
<split-view-divider-position>290</split-view-divider-position>
<outline x="0" y="0" w="275" h="900">
<column name="IM" width="20"/>
<column name="Notes" width="20"/>
<column name="Type" width="49"/>
<column name="Resource" width="139"/>
<column name="Custom Work Week" width="20"/>
<column name="Schedule Exception" width="20"/>
</outline>
</calendar>
</window>
<project>
<next-task-id>10</next-task-id>
<next-resource-id>5</next-resource-id>
<scenario id="mFlQ8Rl4Gch" name="Actual" filename="Actual.xml"/>
<date-display dates="true" times="true" seconds="false"/>
<numbering-style>wbs</numbering-style>
<critical-path-slack>0</critical-path-slack>
<currency-format>CN¥1,234.56</currency-format>
<duration-format hours-per-day="8" hours-per-week="40" hours-per-month="160" hours-per-year="1920" hours="true" days="true" weeks="true"/>
<effort-format hours-per-day="8" hours-per-week="40" hours-per-month="160" hours-per-year="1920" hours="true" days="true" weeks="true"/>
<base-style>
<style/>
</base-style>
<column-title-style>
<style>
<value key="font-weight">9</value>
<value key="paragraph-alignment">center</value>
</style>
</column-title-style>
<note-style>
<style>
<value key="font-family">Helvetica</value>
<value key="font-fill">
<color w="0.334677"/>
</value>
<value key="font-size">11</value>
</style>
</note-style>
<standard-task-style>
<style/>
</standard-task-style>
<overdue-task-style>
<style/>
</overdue-task-style>
<completed-task-style>
<style/>
</completed-task-style>
<group-task-style>
<style>
<value key="font-weight">9</value>
</style>
</group-task-style>
<milestone-task-style>
<style/>
</milestone-task-style>
<resource-style>
<style/>
</resource-style>
<not-editable-style>
<style>
<value key="font-fill">
<color w="0.334677"/>
</value>
</style>
</not-editable-style>
<subscribe-refresh>0</subscribe-refresh>
<leveling>
<constrains-completion-date/>
</leveling>
<page-adornment>
<master-page-headers>
<header location="left">
<text>
<p>
<run>
<lit><cell variable="OPDocumentTitleVariableIdentifier"/></lit>
</run>
</p>
</text>
</header>
<header location="right">
<text>
<p>
<run>
<lit><cell variable="OPPrintJobTimestampVariableIdentifier"/></lit>
</run>
</p>
</text>
</header>
<footer location="left">
<text>
<p>
<run>
<lit><cell variable="OPDocumentFilenameVariableIdentifier"/></lit>
</run>
</p>
</text>
</footer>
<footer location="right">
<text>
<p>
<run>
<lit><cell variable="OPPageNumberVariableIdentifier"/></lit>
</run>
</p>
</text>
</footer>
</master-page-headers>
</page-adornment>
</project>
</omniplan>
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<changelog xmlns="http://www.omnigroup.com/namespace/OmniPlan/v2">
<version>2.1</version>
<task-change-set user="campaign" date="2014-02-11T09:53:33.500Z" timestamp="2014-02-11T09:53:33.500Z">
<change idref="t2" to="t-1" to-position="1" resolved="yes">
<change idref="t2" attribute="effort" type="real" from="28800" to="57600"/>
<change idref="t2" attribute="internalAssignments" type="string" from="" to="3; 4"/>
<change idref="t2" attribute="noEarlierThanConstraintDate" type="date" to="2014-02-12T00:00:00.000Z"/>
<change idref="t2" attribute="title" type="string" to="undo/redo"/>
</change>
<change idref="t3" to="t-1" to-position="2" resolved="yes">
<change idref="t3" attribute="internalAssignments" type="string" from="" to="3"/>
<change idref="t3" attribute="title" type="string" to="layout"/>
</change>
<change idref="t4" to="t-1" to-position="3" resolved="yes">
<change idref="t4" attribute="effort" type="real" from="28800" to="57600"/>
<change idref="t4" attribute="internalAssignments" type="string" from="" to="2"/>
<change idref="t4" attribute="noEarlierThanConstraintDate" type="date" to="2014-02-17T00:00:00.000Z"/>
<change idref="t4" attribute="title" type="string" to="拖放,改变子树"/>
</change>
<change idref="t5" to="t-1" to-position="4" resolved="yes">
<change idref="t5" attribute="effort" type="real" from="28800" to="86400"/>
<change idref="t5" attribute="internalAssignments" type="string" from="" to="3"/>
<change idref="t5" attribute="noEarlierThanConstraintDate" type="date" to="2014-02-13T00:00:00.000Z"/>
<change idref="t5" attribute="title" type="string" to="添加icon"/>
</change>
<change idref="t6" to="t-1" to-position="5" resolved="yes">
<change idref="t6" attribute="effort" type="real" from="28800" to="55800"/>
<change idref="t6" attribute="internalAssignments" type="string" from="" to="2; 3"/>
<change idref="t6" attribute="noEarlierThanConstraintDate" type="date" to="2014-02-19T00:00:00.000Z"/>
<change idref="t6" attribute="title" type="string" to="ui美化"/>
</change>
<change idref="t7" to="t-1" to-position="6" resolved="yes">
<change idref="t7" attribute="effort" type="real" from="28800" to="115200"/>
<change idref="t7" attribute="internalAssignments" type="string" from="" to="2; 3"/>
<change idref="t7" attribute="noEarlierThanConstraintDate" type="date" to="2014-02-20T00:00:00.000Z"/>
<change idref="t7" attribute="title" type="string" to="官网"/>
</change>
<change idref="t1" attribute="title" type="string" from="Task 1" to="数据导入导出" resolved="yes"/>
<change idref="t1" attribute="effort" type="real" from="28800" to="86400" resolved="yes"/>
<change idref="t1" attribute="internalAssignments" type="string" from="" to="2" resolved="yes"/>
<change idref="t1" attribute="noEarlierThanConstraintDate" type="date" to="2014-02-12T00:00:00.000Z" resolved="yes"/>
</task-change-set>
<task-change-set user="campaign" date="2014-02-12T09:05:14.521Z" timestamp="2014-02-12T09:05:14.521Z">
<change idref="t8" to="t-1" to-position="7">
<change idref="t8" attribute="effort" type="real" from="28800" to="0"/>
<change idref="t8" attribute="isSplittableTask" type="real" from="1" to="0"/>
<change idref="t8" attribute="noEarlierThanConstraintDate" type="date" to="2014-02-24T01:00:00.000Z"/>
<change idref="t8" attribute="percentCompleteForMilestone" type="real" to="0"/>
<change idref="t8" attribute="taskType" type="real" from="0" to="1"/>
<change idref="t8" attribute="title" type="string" to="提测"/>
</change>
<change idref="t3" attribute="effort" type="real" from="28800" to="27900"/>
<change idref="t3" attribute="noEarlierThanConstraintDate" type="date" to="2014-02-11T00:15:00.000Z"/>
</task-change-set>
<task-change-set user="campaign" date="2014-02-12T10:24:17.663Z" timestamp="2014-02-12T10:24:17.663Z">
<change idref="t6" from="t-1" from-position="5" to="t-1" to-position="4"/>
<change idref="t1" attribute="effort" type="real" from="86400" to="28800"/>
<change idref="t1" attribute="styleDict" type="dict" to="{
&quot;font-fill&quot; = {
b = 1;
g = &quot;0.436444&quot;;
r = &quot;0.299775&quot;;
};
}"/>
<change idref="t1" attribute="internalEffortDone" type="real" from="0" to="28800"/>
<change idref="t2" attribute="styleDict" type="dict" to="{
&quot;font-fill&quot; = {
b = 1;
g = &quot;0.436444&quot;;
r = &quot;0.299775&quot;;
};
}"/>
<change idref="t2" attribute="internalEffortDone" type="real" from="0" to="57600"/>
<change idref="t3" attribute="styleDict" type="dict" to="{
&quot;font-fill&quot; = {
b = 1;
g = &quot;0.436444&quot;;
r = &quot;0.299775&quot;;
};
}"/>
<change idref="t3" attribute="internalEffortDone" type="real" from="0" to="27900"/>
<change idref="t4" attribute="noEarlierThanConstraintDate" type="date" from="2014-02-17T00:00:00.000Z" to="2014-02-13T00:00:00.000Z"/>
<change idref="t6" attribute="noEarlierThanConstraintDate" type="date" from="2014-02-19T00:00:00.000Z" to="2014-02-17T00:00:00.000Z"/>
<change idref="t7" attribute="noEarlierThanConstraintDate" type="date" from="2014-02-20T00:00:00.000Z" to="2014-02-18T00:00:00.000Z"/>
<change idref="t8" attribute="title" type="string" from="提测" to="提测 "/>
<change idref="t8" attribute="percentCompleteForMilestone" type="real" from="0" to="1"/>
<change idref="t8" attribute="noEarlierThanConstraintDate" type="date" from="2014-02-24T01:00:00.000Z" to="2014-02-20T00:45:00.000Z"/>
</task-change-set>
<resource-change-set user="campaign" date="2014-02-11T09:53:33.500Z" timestamp="2014-02-11T09:53:33.500Z">
<change idref="r2" to="r-1" to-position="1" resolved="yes">
<change idref="r2" attribute="name" type="string" to="家鸣"/>
</change>
<change idref="r3" to="r-1" to-position="2" resolved="yes">
<change idref="r3" attribute="name" type="string" to="潘"/>
</change>
<change idref="r4" to="r-1" to-position="3" resolved="yes">
<change idref="r4" attribute="name" type="string" to="战"/>
</change>
</resource-change-set>
<metadata-change-set user="campaign" date="2014-02-11T09:53:33.500Z" timestamp="2014-02-11T09:53:33.500Z">
<change idref="m1" attribute="fixedDate" type="date" from="2007-01-01T20:00:00.000Z" to="2014-02-11T00:00:00.000Z" resolved="yes"/>
</metadata-change-set>
</changelog>
...@@ -10,11 +10,13 @@ KityMinder.LANG[ 'zh-cn' ] = { ...@@ -10,11 +10,13 @@ KityMinder.LANG[ 'zh-cn' ] = {
'fontfamily': '字体', 'fontfamily': '字体',
'fontsize': '字号', 'fontsize': '字号',
'layoutstyle': '主题', 'layoutstyle': '主题',
'node': '节点操作',
'saveto': '导出', 'saveto': '导出',
'hand': '允许拖拽', 'hand': '允许拖拽',
'zoom-in': '放大', 'zoom-in': '放大',
'zoom-out': '缩小', 'zoom-out': '缩小',
'markers': '添加标签' 'markers': '添加标签',
'switchlayout': '切换主题'
}, },
'popupcolor': { 'popupcolor': {
'clearColor': '清空颜色', 'clearColor': '清空颜色',
...@@ -35,9 +37,14 @@ KityMinder.LANG[ 'zh-cn' ] = { ...@@ -35,9 +37,14 @@ KityMinder.LANG[ 'zh-cn' ] = {
'quarterdone': '完成1/4', 'quarterdone': '完成1/4',
'halfdone': '完成1/2', 'halfdone': '完成1/2',
'threequartersdone': '完成3/4', 'threequartersdone': '完成3/4',
'done': '已完成', 'done': '已完成'
} }
} }
},
'node': {
'appendsiblingnode': '插入兄弟节点',
'appendchildnode': '插入孩子节点',
'removenode': '删除节点'
} }
}; };
\ No newline at end of file
测试要点
1. 操作模式
1.1 常规模式
1.1.1 只在该模式允许的操作:`节点选择`、`创建新节点`、`拖动到父节点`
1.2 拖动模式
1.1.2 只在该模式允许的操作:`画布拖放`
1.3 文本编辑模式
1.1.3 只在该模式允许的操作:`文本框选`、`文本编辑`
1.4 模式切换
1.4.1 常规模式下,在单个选中的节点上点击文字区域(多选的情况下不算),进入文本编辑模式,并且光标定在点击的位置上
1.4.2 常规模式下,在任意节点上双击文字区域,进入文本编辑模式,并且文本被选中
1.4.3 常规模式下,创建了新节点的时候,进入文本编辑模式,新节点文本被选中
1.4.4 常规模式下,有唯一选中的节点,按下字母和数字的按键会进入文本编辑模式,并且文字变为刚输入的字母或数字,或是弹出输入法框
1.4.5 文本编辑模式下,按 Tab 和 Enter 退出文本编辑模式,回到常规模式
1.4.6 文本编辑模式下,点击非文本区域的任何位置,退出文本编辑模式,回到常规模式
1.4.7 常规模式下,按 Space 或点击 UI 上的拖动图标进入拖动模式
1.4.8 拖动模式下,按 Space 或点击 UI 上的拖动图标退出拖动模式,回到常规模式
2. `节点选择` 交互
2.1 该交互只在常规模式下有效
2.2 点击任意未被选中的节点,会使其选中
2.3 点击空白处,会取消节点的选择
2.4 按着 Shift 键,点击的节点会切换选择状态
2.5 在空白处按下鼠标并移动10像素后,会显示选框;当选框跟节点有重合的时候,节点会被选中,没有重合的节点不被选中
2.6 按键盘方向键的时候:
2.6.1 对于一个节点“方向”的定义为:
2.6.1.1 以节点为坐标原点的直角坐标系顺时针旋转45度,第一象限为“上”,第二象限为“左”,第三象限为“右”,第四象限为“下”
2.6.2 假如当前没有节点被选中,任何方向键都将选中根节点
2.6.3 假如当前有唯一选中的节点,将导航至指定方向区域的最近的节点
2.6.4 假如有多个选择的节点,以选择顺序第一个节点为参照,导航至其指定方向区域的最近的节点
2.6.5 假如被导航的区域中没有节点,选区保持不变
3. `创建新节点` 交互
3.1 目标节点定义为:
3.1.1 如果有唯一选中的节点,其为目标节点
3.1.2 如果有多个选中的节点,则首个(时间上)被选中的节点为目标节点
3.2 如果存在目标节点:
3.2.1 按下键盘的 Tab 键,会创建一个目标节点的子节点,并且新节点在唯一选中状态,模式变为文本编辑模式
3.2.2 按下键盘的 Enter 键,并且目标节点不是根节点,会创建一个目标节点的兄弟节点(紧邻的位置上),并且新节点在唯一选中,模式变为文本编辑模式
3.3 如果存在目标节点:
3.3.1 创建子节点的 UI 是可用的,否则不可用
3.3.2 如果目标节点是根节点,则创建兄弟节点的 UI 是不可用的,否则是可用的
3.4 该交互只在常规模式下有效
4. `拖放到父节点` 交互
4.1 该交互只在常规模式下有效
4.2 在任意节点上 mousedown,并且移动10像素以上,确定拖放对象:
4.2.1 如果节点没被选中,则节点被选中,并且作为拖动对象
4.2.2 如果节点是被选中的,则所有选中的节点作为拖放对象
4.3 排除无效拖放对象:
4.3.1 如果存在一个拖放对象A和另一个拖放对象B,A是B的祖先,则B被排除
4.3.2 排除后剩余的对象成为真正的拖放对象
4.4 拖放对象表示为一个拖放图形,并且显示拖放对象的数量
4.5 拖放图形随鼠标移动,并且每次移动会判断是否遇到拖放目标:
4.5.1 拖放对象本身以及整棵子树都不能作为拖放目标
4.5.2 如果拖放图形和拖放目标的图形有重合,拖放目标会高亮,否则不会高亮
4.6 如果在遇到拖放目标的时候释放鼠标(mouseup),会让拖放对象成为拖放目标的子节点,并且:
4.6.1 保持之前拖放目标的选中状态
4.6.2 保证拖放目标的顺序与拖放之前保持一致
5. `画布导航` 交互
5.1 该交互只在拖动模式下有效
5.2 在任意位置鼠标按下(mousedown)之后画布可以随鼠标移动
5.3 鼠标释放(mouseup)之后画布不再随鼠标移动
5.4 按下方向键会让画布用动画朝反方向移动一定的距离
6. `画布缩放` 交互
6.1 在非文本编辑模式下,点击 `+` 和 `-` 分别可以拉近视野(放大画布)和拉远视野(缩小画布)
6.2 在任意模式下,使用鼠标滚轮可以缩放视野
6.2.1 往上滚动拉近视野
6.2.3 往下滚动拉远视野
6.3 在任意模式下,UI 上的 zoom-in 和 zoom-out 分别可以拉近视野和拉远视野
6.4 视野拉远和拉近都有最值,不能无限操作;当每个操作不可用的时候,UI 上的按钮呈不可用状态
7. `文本框选` 和 `文本编辑` 和默认行为一致即可
8. `字体样式` 功能
8.1 该功能在 `拖放模式` 下不可用
8.2 包括的子功能:
8.2.1 加粗
8.2.2 斜体
8.2.3 字体
8.2.4 字号
8.2.5 颜色
8.3 所有的子功能以节点为单位设置和读取
8.4 对于选中的节点在 UI 上应该反映当前的样式状态
8.5 UI 上设置样式针对所有选中的节点生效
8.6 没有选中节点的时候,UI 上的功能按钮应该呈不可用状态
9. `子节点收缩功能`
9.1 在一级节点及以上,如果存在子节点,显示收缩功能的图标,否则不显示
9.2 收缩图标显示 `-` 的时候,子节点显示;收缩图标显示 `+` 的时候,子节点不显示;点击图标切换这两种状态
10. `节点删除功能`
10.1 目标节点的计算方法同拖放到父节点的拖放目标的计算方法
10.2 如果目标节点包含根,把根从目标节点中移除
10.3 如果包含删除目标,删除操作的 UI 是可用的,否则是不可用的
10.4 把所有目标节点从其父节点中移除
11. `标签功能`
11.1 对于选中的节点,点击优先级标签和完成度标签可以在节点文本前添加标签图形
11.2 对于同一类的标签,只能添加一个标签
11.3 选中单个节点的时候,标签面板显示选中节点的当前标签;
11.4 多选的情况下,如果标签一致以任意一个节点为准来显示状态;标签不一致显示所有包含的状态
12. `导入导出功能`
12.1 导出数据应该能下载一个文件
12.2 下载的文件拖动到画布上,可以还原原来的数据
KM.registerToolbarUI( 'layoutstyle fontfamily fontsize', function ( name ) { KM.registerToolbarUI( 'fontfamily fontsize', function ( name ) {
var me = this, var me = this,
label = me.getLang( 'tooltips.' + name ), label = me.getLang( 'tooltips.' + name ),
...@@ -19,9 +19,7 @@ KM.registerToolbarUI( 'layoutstyle fontfamily fontsize', function ( name ) { ...@@ -19,9 +19,7 @@ KM.registerToolbarUI( 'layoutstyle fontfamily fontsize', function ( name ) {
} }
switch ( name ) { switch ( name ) {
case 'layoutstyle':
options = transForLayoutstyle( options );
break;
case 'fontfamily': case 'fontfamily':
options = transForFontfamily( options ); options = transForFontfamily( options );
...@@ -62,24 +60,6 @@ KM.registerToolbarUI( 'layoutstyle fontfamily fontsize', function ( name ) { ...@@ -62,24 +60,6 @@ KM.registerToolbarUI( 'layoutstyle fontfamily fontsize', function ( name ) {
return comboboxWidget.button().addClass( 'kmui-combobox' ); return comboboxWidget.button().addClass( 'kmui-combobox' );
function transForLayoutstyle( options ) {
var tempItems = [];
utils.each( options.items, function ( k, v ) {
options.value.push( k );
tempItems.push( k );
options.autowidthitem.push( $.wordCountAdaptive( tempItems[ tempItems.length - 1 ] ) );
} );
options.items = tempItems;
return options;
}
//字体参数转换 //字体参数转换
function transForFontfamily( options ) { function transForFontfamily( options ) {
......
KM.registerToolbarUI( 'switchlayout', function ( name ) {
var me = this,
label = me.getLang( 'tooltips.' + name ),
options = {
label: label,
title: label,
comboboxName: name,
items: me.getLayoutStyleItems() || [],
itemStyles: [],
value: me.getLayoutStyleItems(),
autowidthitem: [],
enabledRecord:false
},
$combox = null;
if ( options.items.length == 0 ) {
return null;
}
//实例化
$combox = $.kmuibuttoncombobox( options ).css( 'zIndex', me.getOptions( 'zIndex' ) + 1 );
comboboxWidget = $combox.kmui();
comboboxWidget.on( 'comboboxselect', function ( evt, res ) {
me.execCommand( name, res.value );
} ).on( "beforeshow", function () {
if ( $combox.parent().length === 0 ) {
$combox.appendTo( me.$container.find( '.kmui-dialog-container' ) );
}
} );
//状态反射
me.on( 'interactchange', function () {
var state = this.queryCommandState( name ),
value = this.queryCommandValue( name );
//设置按钮状态
comboboxWidget.button().kmui().disabled( state == -1 ).active( state == 1 );
if ( value ) {
//设置label
value = value.replace( /['"]/g, '' ).toLowerCase().split( /['|"]?\s*,\s*[\1]?/ );
comboboxWidget.selectItemByLabel( value );
}
} );
return comboboxWidget.button().addClass( 'kmui-combobox' );
} );
\ No newline at end of file
KM.registerToolbarUI( 'node', function ( name ) {
var shortcutKeys = {
"appendsiblingnode": "enter",
"appendchildnode": "tab",
"removenode": "del|backspace"
};
var me = this,
msg = me.getLang( 'node' ),
label = me.getLang( 'tooltips.' + name ),
options = {
label: label,
title: label,
comboboxName: name,
items: me.getOptions( name ) || [],
itemStyles: [],
value: [],
autowidthitem: [],
enabledRecord: false
},
$combox = null;
if ( options.items.length == 0 ) {
return null;
}
//实例化
$combox = $.kmuibuttoncombobox( transForInserttopic( options ) ).css( 'zIndex', me.getOptions( 'zIndex' ) + 1 );
comboboxWidget = $combox.kmui();
comboboxWidget.on( 'comboboxselect', function ( evt, res ) {
me.execCommand( res.value, new MinderNode( me.getLang().topic ) );
} ).on( "beforeshow", function () {
if ( $combox.parent().length === 0 ) {
$combox.appendTo( me.$container.find( '.kmui-dialog-container' ) );
}
var combox = $combox.kmui();
combox.traverseItems( function ( label, value ) {
if ( me.queryCommandState( value ) == -1 ) {
combox.disableItemByLabel( label )
} else {
combox.enableItemByLabel( label )
}
} )
} );
return comboboxWidget.button().addClass( 'kmui-combobox' );
function transForInserttopic( options ) {
var tempItems = [];
utils.each( options.items, function ( k, v ) {
options.value.push( v );
tempItems.push( ( msg[ k ] || k ) + '(' + shortcutKeys[ v ].toUpperCase() + ')' );
options.autowidthitem.push( $.wordCountAdaptive( tempItems[ tempItems.length - 1 ] ) );
} );
options.items = tempItems;
return options;
}
} );
\ No newline at end of file
...@@ -9,7 +9,8 @@ KM.registerToolbarUI( 'saveto', function ( name ) { ...@@ -9,7 +9,8 @@ KM.registerToolbarUI( 'saveto', function ( name ) {
items: [], items: [],
itemStyles: [], itemStyles: [],
value: [], value: [],
autowidthitem: [] autowidthitem: [],
enabledRecord:false
}, },
$combox = null, $combox = null,
comboboxWidget = null; comboboxWidget = null;
...@@ -30,6 +31,53 @@ KM.registerToolbarUI( 'saveto', function ( name ) { ...@@ -30,6 +31,53 @@ KM.registerToolbarUI( 'saveto', function ( name ) {
comboboxWidget = $combox.kmui(); comboboxWidget = $combox.kmui();
comboboxWidget.on( 'comboboxselect', function ( evt, res ) { comboboxWidget.on( 'comboboxselect', function ( evt, res ) {
if ( res.value === "png" ) {
var svghtml = $( "#kityminder .kmui-editor-body" ).html();
var rootBox = me.getRoot().getRenderContainer().getRenderBox();
var svg = $( svghtml ).attr( {
width: rootBox.x + me.getRenderContainer().getWidth() + 20,
height: rootBox.y + me.getRenderContainer().getHeight() + 20,
viewBox: null
} );
var div = $( "<div></div>" ).append( svg );
svghtml = div.html();
var canvas = $( '<canvas style="border:2px solid black;" width="' + svg.attr( "width" ) + '" height="' + svg.attr( "height" ) + '"></canvas>' );
var ctx = canvas[ 0 ].getContext( "2d" );
var DOMURL = self.URL || self.webkitURL || self;
var img = new Image();
var svg = new Blob( [ svghtml ], {
type: "image/svg+xml;charset=utf-8"
} );
var url = DOMURL.createObjectURL( svg );
img.onload = function () {
ctx.drawImage( img, 0, 0 );
DOMURL.revokeObjectURL( url );
var type = 'png';
var imgData = canvas[ 0 ].toDataURL( type );
var _fixType = function ( type ) {
type = type.toLowerCase().replace( /jpg/i, 'jpeg' );
var r = type.match( /png|jpeg|bmp|gif/ )[ 0 ];
return 'image/' + r;
};
imgData = imgData.replace( _fixType( type ), 'image/octet-stream' );
var saveFile = function ( data, filename ) {
var save_link = document.createElementNS( 'http://www.w3.org/1999/xhtml', 'a' );
save_link.href = data;
save_link.download = filename;
var event = document.createEvent( 'MouseEvents' );
event.initMouseEvent( 'click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null );
save_link.dispatchEvent( event );
};
// 下载后的问题名
var filename = 'kityminder_' + ( new Date() ).getTime() + '.' + type;
// download
saveFile( imgData, filename );
};
img.src = url;
return "png";
}
var data = me.exportData( res.value ); var data = me.exportData( res.value );
var p = KityMinder.findProtocal( res.value ); var p = KityMinder.findProtocal( res.value );
var a = downloadLink; var a = downloadLink;
......
...@@ -28,5 +28,14 @@ var keymap = KityMinder.keymap = { ...@@ -28,5 +28,14 @@ var keymap = KityMinder.keymap = {
'NumLock':144, 'NumLock':144,
'Cmd':91 'Cmd':91,
'=':187,
'-':189,
"b":66,
'i':73,
'z':90,
'y':89
}; };
\ No newline at end of file
...@@ -69,6 +69,9 @@ var Minder = KityMinder.Minder = kity.createClass( "KityMinder", { ...@@ -69,6 +69,9 @@ var Minder = KityMinder.Minder = kity.createClass( "KityMinder", {
this._shortcutkeys = {}; this._shortcutkeys = {};
this._bindshortcutKeys(); this._bindshortcutKeys();
}, },
isTextEditStatus:function(){
return false;
},
addShortcutKeys: function ( cmd, keys ) { addShortcutKeys: function ( cmd, keys ) {
var obj = {},km = this; var obj = {},km = this;
if ( keys ) { if ( keys ) {
...@@ -87,25 +90,50 @@ var Minder = KityMinder.Minder = kity.createClass( "KityMinder", { ...@@ -87,25 +90,50 @@ var Minder = KityMinder.Minder = kity.createClass( "KityMinder", {
_bindshortcutKeys: function () { _bindshortcutKeys: function () {
var me = this, var me = this,
shortcutkeys = this._shortcutkeys; shortcutkeys = this._shortcutkeys;
me.on( 'keydown', function ( e ) { function checkkey(key,keyCode,e){
switch(key){
case 'ctrl':
case 'cmd':
if(e.ctrlKey || e.metaKey){
return true;
}
break;
case 'alt':
if(e.altKey){
return true
}
break;
case 'shift':
if(e.shiftKey){
return true;
}
}
if(keyCode == keymap[key]){
return true;
}
return false
}
me.on( 'keydown', function ( e ) {
var originEvent = e.originEvent; var originEvent = e.originEvent;
var keyCode = originEvent.keyCode || originEvent.which; var keyCode = originEvent.keyCode || originEvent.which;
for ( var i in shortcutkeys ) { for ( var i in shortcutkeys ) {
var tmp = shortcutkeys[ i ].split( ',' ); var keys = shortcutkeys[ i ].toLowerCase().split('+');
for ( var t = 0, ti; ti = tmp[ t++ ]; ) { var current = 0;
ti = ti.split( ':' ); utils.each(keys,function(i,k){
var key = ti[ 0 ], if(checkkey(k,keyCode,originEvent)){
param = ti[ 1 ]; current++;
if ( /^(ctrl)(\+shift)?\+(\d+)$/.test( key.toLowerCase() ) || /^(\d+)$/.test( key ) ) {
if ( ( ( RegExp.$1 == 'ctrl' ? ( originEvent.ctrlKey || originEvent.metaKey ) : 0 ) && ( RegExp.$2 != "" ? originEvent[ RegExp.$2.slice( 1 ) + "Key" ] : 1 ) && keyCode == RegExp.$3 ) ||
keyCode == RegExp.$1
) {
if ( me.queryCommandState( i, param ) != -1 )
me.execCommand( i, param );
e.preventDefault();
} }
});
//todo 暂时通过receiver判断
if(me.isTextEditStatus()){
return;
} }
if(current == keys.length){
if ( me.queryCommandState( i ) != -1 )
me.execCommand( i );
originEvent.preventDefault();
break;
} }
} }
......
...@@ -69,8 +69,8 @@ KityMinder.registerModule( "basestylemodule", function () { ...@@ -69,8 +69,8 @@ KityMinder.registerModule( "basestylemodule", function () {
} ) } )
}, },
addShortcutKeys: { addShortcutKeys: {
"bold": "ctrl+66", //bold "bold": "ctrl+b", //bold
"italic": "ctrl+73" //italic "italic": "ctrl+i" //italic
}, },
"events": { "events": {
"beforeRenderNode": function ( e ) { "beforeRenderNode": function ( e ) {
......
...@@ -32,7 +32,7 @@ var MoveToParentCommand = kity.createClass( 'MoveToParentCommand', { ...@@ -32,7 +32,7 @@ var MoveToParentCommand = kity.createClass( 'MoveToParentCommand', {
function boxMapper( node ) { function boxMapper( node ) {
return node.getRenderContainer().getRenderBox(); return node.getRenderContainer().getRenderBox( 'top' );
} }
// 对拖动对象的一个替代盒子,控制整个拖放的逻辑,包括: // 对拖动对象的一个替代盒子,控制整个拖放的逻辑,包括:
...@@ -79,6 +79,12 @@ var DragBox = kity.createClass( "DragBox", { ...@@ -79,6 +79,12 @@ var DragBox = kity.createClass( "DragBox", {
ancestors = [], ancestors = [],
judge; judge;
// 根节点不参与计算
var rootIndex = nodes.indexOf( this._minder.getRoot() );
if ( ~rootIndex ) {
nodes.splice( rootIndex, 1 );
}
// 判断 nodes 列表中是否存在 judge 的祖先 // 判断 nodes 列表中是否存在 judge 的祖先
function hasAncestor( nodes, judge ) { function hasAncestor( nodes, judge ) {
for ( var i = nodes.length - 1; i >= 0; --i ) { for ( var i = nodes.length - 1; i >= 0; --i ) {
...@@ -137,10 +143,15 @@ var DragBox = kity.createClass( "DragBox", { ...@@ -137,10 +143,15 @@ var DragBox = kity.createClass( "DragBox", {
// 4. 标记已启动 // 4. 标记已启动
_enterDragMode: function () { _enterDragMode: function () {
this._calcDragSources(); this._calcDragSources();
if ( !this._dragSources.length ) {
this._startPosition = null;
return false;
}
this._calcDropTargets(); this._calcDropTargets();
this._drawForDragMode(); this._drawForDragMode();
this._shrink(); this._shrink();
this._dragMode = true; this._dragMode = true;
return true;
}, },
_leaveDragMode: function () { _leaveDragMode: function () {
this.remove(); this.remove();
...@@ -227,16 +238,21 @@ var DragBox = kity.createClass( "DragBox", { ...@@ -227,16 +238,21 @@ var DragBox = kity.createClass( "DragBox", {
}, },
dragMove: function ( position ) { dragMove: function ( position ) {
// 启动拖放模式需要最小的移动距离
var DRAG_MOVE_THRESHOLD = 10;
if ( !this._startPosition ) return; if ( !this._startPosition ) return;
this._dragPosition = position; this._dragPosition = position;
if ( !this._dragMode ) { if ( !this._dragMode ) {
// 判断拖放模式是否该启动 // 判断拖放模式是否该启动
if ( GM.getDistance( this._dragPosition, this._startPosition ) < 10 ) { if ( GM.getDistance( this._dragPosition, this._startPosition ) < DRAG_MOVE_THRESHOLD ) {
return;
}
if ( !this._enterDragMode() ) {
return; return;
} }
this._enterDragMode();
} }
var movement = kity.Vector.fromPoints( this._startPosition, this._dragPosition ); var movement = kity.Vector.fromPoints( this._startPosition, this._dragPosition );
...@@ -269,7 +285,8 @@ KityMinder.registerModule( "DragTree", function () { ...@@ -269,7 +285,8 @@ KityMinder.registerModule( "DragTree", function () {
}, },
events: { events: {
mousedown: function ( e ) { mousedown: function ( e ) {
if ( e.getTargetNode() ) { // 单选中根节点也不触发拖拽
if ( e.getTargetNode() && e.getTargetNode() != this.getRoot() ) {
this._dragBox.dragStart( e.getPosition() ); this._dragBox.dragStart( e.getPosition() );
} }
}, },
......
...@@ -14,6 +14,12 @@ KityMinder.registerModule( "TextEditModule", function () { ...@@ -14,6 +14,12 @@ KityMinder.registerModule( "TextEditModule", function () {
km.isTextEditStatus = function(){
return km.receiver.isTextEditStatus();
};
var selectionByClick = false;
return { return {
//插入光标 //插入光标
"init":function(){ "init":function(){
...@@ -23,12 +29,19 @@ KityMinder.registerModule( "TextEditModule", function () { ...@@ -23,12 +29,19 @@ KityMinder.registerModule( "TextEditModule", function () {
'beforemousedown':function(e){ 'beforemousedown':function(e){
sel.setHide(); sel.setHide();
var node = e.getTargetNode(); var node = e.getTargetNode();
if(!node){
var selectionShape = e.kityEvent.targetShape;
if(selectionShape && selectionShape.getType() == 'Selection'){
selectionByClick = true;
node = selectionShape.getData('relatedNode');
e.stopPropagationImmediately();
}
}
if(node){ if(node){
var textShape = node.getTextShape(); var textShape = node.getTextShape();
textShape.setStyle('cursor','default'); textShape.setStyle('cursor','default');
if ( this.isSingleSelect() && node.isSelected() && e.kityEvent.targetShape.getType().toLowerCase()== 'text') { if ( this.isSingleSelect() && node.isSelected()) {// && e.kityEvent.targetShape.getType().toLowerCase()== 'text'
sel.collapse(); sel.collapse();
node.getTextShape().setStyle('cursor','text'); node.getTextShape().setStyle('cursor','text');
receiver.setTextEditStatus(true) receiver.setTextEditStatus(true)
...@@ -42,27 +55,44 @@ KityMinder.registerModule( "TextEditModule", function () { ...@@ -42,27 +55,44 @@ KityMinder.registerModule( "TextEditModule", function () {
.setCurrentIndex(e.getPosition()) .setCurrentIndex(e.getPosition())
.updateSelection() .updateSelection()
.setRange(range); .setRange(range);
sel.setData('relatedNode',node);
mouseDownStatus = true; mouseDownStatus = true;
lastEvtPosition = e.getPosition(); lastEvtPosition = e.getPosition();
if(selectionByClick){
sel.setShow();
selectionByClick = false;
}
} }
} }
}, },
'mouseup':function(e){ 'mouseup':function(e){
if(!sel.collapsed && mouseDownStatus){ if(mouseDownStatus){
if(!sel.collapsed ){
receiver.updateRange(range) receiver.updateRange(range)
}else
sel.setShow()
} }
mouseDownStatus = false; mouseDownStatus = false;
oneTime = 0; oneTime = 0;
}, },
'beforemousemove':function(e){ 'beforemousemove':function(e){
if(mouseDownStatus){ if(mouseDownStatus){
e.stopPropagationImmediately(); e.stopPropagationImmediately();
var offset = e.getPosition(); var offset = e.getPosition();
if(Math.abs(offset.y - lastEvtPosition.y) > 2 && Math.abs(lastEvtPosition.x - offset.x) < 1 ){
sel.setHide();
mouseDownStatus = false;
return;
}
dir = offset.x > lastEvtPosition.x ? 1 : (offset.x < lastEvtPosition.x ? -1 : dir); dir = offset.x > lastEvtPosition.x ? 1 : (offset.x < lastEvtPosition.x ? -1 : dir);
receiver.updateSelectionByMousePosition(offset,dir) receiver.updateSelectionByMousePosition(offset,dir)
.updateSelectionShow(dir); .updateSelectionShow(dir);
sel.stroke('none',0);
lastEvtPosition = e.getPosition(); lastEvtPosition = e.getPosition();
} }
}, },
'dblclick':function(e){ 'dblclick':function(e){
...@@ -73,8 +103,8 @@ KityMinder.registerModule( "TextEditModule", function () { ...@@ -73,8 +103,8 @@ KityMinder.registerModule( "TextEditModule", function () {
sel.setStartOffset(0); sel.setStartOffset(0);
sel.setEndOffset(text.getContent().length); sel.setEndOffset(text.getContent().length);
sel.setShow(); sel.setShow();
receiver.updateSelectionShow(1) receiver.setContainerTxt(text.getContent()).updateSelectionShow(1)
.updateRange(range); .updateRange(range).setTextEditStatus(true)
} }
}, },
...@@ -117,7 +147,7 @@ KityMinder.registerModule( "TextEditModule", function () { ...@@ -117,7 +147,7 @@ KityMinder.registerModule( "TextEditModule", function () {
receiver.updateSelectionShow(1) receiver.updateSelectionShow(1)
.updateRange(range); .updateRange(range);
return;
} }
...@@ -130,10 +160,11 @@ KityMinder.registerModule( "TextEditModule", function () { ...@@ -130,10 +160,11 @@ KityMinder.registerModule( "TextEditModule", function () {
}else{ }else{
receiver.updateSelectionShow(1) receiver.updateSelectionShow(1)
} }
return;
} }
receiver.clear().setTextEditStatus(false);
}, },
'selectionclear':function(){ 'selectionclear':function(){
receiver.setTextEditStatus(false).clear() receiver.setTextEditStatus(false).clear()
......
...@@ -16,7 +16,12 @@ Minder.Range = kity.createClass('Range',{ ...@@ -16,7 +16,12 @@ Minder.Range = kity.createClass('Range',{
return this; return this;
}, },
setStart:function(node,index){ setStart:function(node,index){
try{
this.nativeRange.setStart(node,index); this.nativeRange.setStart(node,index);
}catch(e){
console.log(e)
}
return this; return this;
}, },
setEnd:function(node,index){ setEnd:function(node,index){
......
...@@ -223,16 +223,17 @@ Minder.Receiver = kity.createClass('Receiver',{ ...@@ -223,16 +223,17 @@ Minder.Receiver = kity.createClass('Receiver',{
return false; return false;
} }
if(offset.x >= v.x && offset.x <= v.x + v.width){ if(offset.x >= v.x && offset.x <= v.x + v.width){
if(me.index == i){ if(me.index == i){
if(i == 0){ if(i == 0){
me.selection.setStartOffset(i) me.selection.setStartOffset(i)
} }
me.selection.setEndOffset(i + (dir == 1 ? 1 : 0)) me.selection.setEndOffset(i + (dir == 1 ? 1 : 0))
}else if(i > me.index){ }else if(i > me.index){
me.selection.setStartOffset(me.index);
me.selection.setEndOffset(i + (dir == 1 ? 1 : 0)) me.selection.setEndOffset(i + (dir == 1 ? 1 : 0))
}else{ }else{
me.selection.setStartOffset(i + (dir == 1 ? 1 : 0)) me.selection.setStartOffset(i + (dir == 1 ? 1 : 0));
me.selection.setEndOffset(me.index)
} }
return false; return false;
...@@ -246,7 +247,7 @@ Minder.Receiver = kity.createClass('Receiver',{ ...@@ -246,7 +247,7 @@ Minder.Receiver = kity.createClass('Receiver',{
width = 0 ; width = 0 ;
if(this.selection.collapsed){ if(this.selection.collapsed){
this.selection.updateShow(startOffset,0); this.selection.updateShow(startOffset||this.textData[this.textData.length-1],0);
return this; return this;
} }
if(!endOffset){ if(!endOffset){
...@@ -269,5 +270,9 @@ Minder.Receiver = kity.createClass('Receiver',{ ...@@ -269,5 +270,9 @@ Minder.Receiver = kity.createClass('Receiver',{
setIndex:function(index){ setIndex:function(index){
this.index = index; this.index = index;
return this return this
},
setContainerTxt:function(txt){
this.container.textContent = txt;
return this;
} }
}); });
\ No newline at end of file
...@@ -5,18 +5,20 @@ Minder.Selection = kity.createClass( 'Selection', { ...@@ -5,18 +5,20 @@ Minder.Selection = kity.createClass( 'Selection', {
this.callBase(); this.callBase();
this.height = height || 20; this.height = height || 20;
this.stroke( color || 'blue', width || 1 ); this.stroke( color || 'rgb(27,171,255)', width || 1 );
this.width = 1; this.width = 0;
this.fill('#99C8FF'); this.fill('rgb(27,171,255)');
this.setHide(); this.setHide();
this.timer = null; this.timer = null;
this.collapsed = true; this.collapsed = true;
this.startOffset = this.endOffset = 0; this.startOffset = this.endOffset = 0;
this.setOpacity(0.5) this.setOpacity(0.5);
this.setStyle('cursor','text');
}, },
collapse : function(toEnd){ collapse : function(toEnd){
this.stroke( 'blue', 1 ); this.stroke( 'rgb(27,171,255)', 1 );
this.setOpacity(1);
this.width = 1; this.width = 1;
this.collapsed = true; this.collapsed = true;
if(toEnd){ if(toEnd){
...@@ -37,7 +39,8 @@ Minder.Selection = kity.createClass( 'Selection', { ...@@ -37,7 +39,8 @@ Minder.Selection = kity.createClass( 'Selection', {
return this; return this;
} }
this.collapsed = false; this.collapsed = false;
this.stroke('none'); this.stroke('none',0);
this.setOpacity(0.5);
return this; return this;
}, },
setEndOffset:function(offset){ setEndOffset:function(offset){
...@@ -51,10 +54,14 @@ Minder.Selection = kity.createClass( 'Selection', { ...@@ -51,10 +54,14 @@ Minder.Selection = kity.createClass( 'Selection', {
return this; return this;
} }
this.collapsed = false; this.collapsed = false;
this.stroke('none'); this.stroke('none',0);
this.setOpacity(0.5);
return this; return this;
}, },
updateShow : function(offset,width){ updateShow : function(offset,width){
if(width){
this.setShowHold();
}
this.setPosition(offset).setWidth(width); this.setPosition(offset).setWidth(width);
return this; return this;
}, },
...@@ -64,7 +71,7 @@ Minder.Selection = kity.createClass( 'Selection', { ...@@ -64,7 +71,7 @@ Minder.Selection = kity.createClass( 'Selection', {
this.y = offset.y; this.y = offset.y;
} catch ( e ) { } catch ( e ) {
console.log(e) debugger
} }
return this.update(); return this.update();
......
...@@ -138,8 +138,8 @@ KityMinder.registerModule( "HistoryModule", function () { ...@@ -138,8 +138,8 @@ KityMinder.registerModule( "HistoryModule", function () {
} ) } )
}, },
addShortcutKeys: { addShortcutKeys: {
"Undo": "ctrl+90", //undo "Undo": "ctrl+z", //undo
"Redo": "ctrl+89" //redo "Redo": "ctrl+y" //redo
}, },
"events": { "events": {
"saveScene": function ( e ) { "saveScene": function ( e ) {
......
...@@ -17,21 +17,24 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -17,21 +17,24 @@ KityMinder.registerModule( "LayoutBottom", function () {
var iconShape = this.shape = new kity.Group(); var iconShape = this.shape = new kity.Group();
iconShape.class = "shicon"; iconShape.class = "shicon";
iconShape.icon = this; iconShape.icon = this;
var circle = this._circle = new kity.Circle().fill( "white" ).stroke( "gray" ).setRadius( 5 ); var rect = this._rect = new kity.Rect().fill( "white" ).stroke( "gray" ).setRadius( 2 ).setWidth( 10 ).setHeight( 10 );
var plus = this._plus = new kity.Path(); var plus = this._plus = new kity.Path();
plus.getDrawer() plus.getDrawer()
.moveTo( -3, 0 ) .moveTo( 2, 5 )
.lineTo( 3, 0 ) .lineTo( 8, 5 )
.moveTo( 0, -3 ) .moveTo( 5, 2 )
.lineTo( 0, 3 ); .lineTo( 5, 8 );
plus.stroke( "gray" ); plus.stroke( "gray" );
var dec = this._dec = new kity.Path(); var dec = this._dec = new kity.Path();
dec.getDrawer() dec.getDrawer()
.moveTo( -3, 0 ) .moveTo( 2, 5 )
.lineTo( 3, 0 ); .lineTo( 8, 5 );
dec.stroke( "gray" ); dec.stroke( "gray" );
minder.getRenderContainer().addShape( iconShape ); if ( node.getType() === "main" ) minder.getRenderContainer().addShape( iconShape );
iconShape.addShapes( [ circle, plus, dec ] ); else {
node.getLayout().subgroup.addShape( iconShape );
}
iconShape.addShapes( [ rect, plus, dec ] );
this.update(); this.update();
this.switchState(); this.switchState();
}, },
...@@ -51,12 +54,9 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -51,12 +54,9 @@ KityMinder.registerModule( "LayoutBottom", function () {
var node = this._node; var node = this._node;
var Layout = node.getLayout(); var Layout = node.getLayout();
var nodeShape = node.getRenderContainer(); var nodeShape = node.getRenderContainer();
var nodeX, nodeY = ( node.getType() === "main" ? Layout.y : ( Layout.y + nodeShape.getHeight() / 2 - 5 ) ); var nodeType = node.getType();
if ( Layout.appendside === "left" ) { var nodeX = nodeShape.getRenderBox().closurePoints[ 1 ].x + 5;
nodeX = nodeShape.getRenderBox().closurePoints[ 1 ].x - 6; var nodeY = nodeShape.getRenderBox().closurePoints[ 0 ].y;
} else {
nodeX = nodeShape.getRenderBox().closurePoints[ 0 ].x + 6;
}
this.shape.setTransform( new kity.Matrix().translate( nodeX, nodeY ) ); this.shape.setTransform( new kity.Matrix().translate( nodeX, nodeY ) );
}, },
remove: function () { remove: function () {
...@@ -64,16 +64,6 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -64,16 +64,6 @@ KityMinder.registerModule( "LayoutBottom", function () {
} }
}; };
} )() ); } )() );
//求并集
var uSet = function ( a, b ) {
for ( var i = 0; i < a.length; i++ ) {
var idx = b.indexOf( a[ i ] );
if ( idx !== -1 ) {
b.splice( idx, 1 );
}
}
return a.concat( b );
};
//样式的配置(包括颜色、字号等) //样式的配置(包括颜色、字号等)
var nodeStyles = { var nodeStyles = {
"root": { "root": {
...@@ -81,8 +71,8 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -81,8 +71,8 @@ KityMinder.registerModule( "LayoutBottom", function () {
fill: '#e9df98', fill: '#e9df98',
fontSize: 24, fontSize: 24,
padding: [ 15.5, 25.5, 15.5, 25.5 ], padding: [ 15.5, 25.5, 15.5, 25.5 ],
margin: [ 0, 0, 0, 0 ], margin: [ 0, 0, 20, 0 ],
radius: 30, radius: 0,
highlight: 'rgb(254, 219, 0)' highlight: 'rgb(254, 219, 0)'
}, },
"main": { "main": {
...@@ -91,17 +81,18 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -91,17 +81,18 @@ KityMinder.registerModule( "LayoutBottom", function () {
color: "#333", color: "#333",
padding: [ 6.5, 20, 6.5, 20 ], padding: [ 6.5, 20, 6.5, 20 ],
fontSize: 16, fontSize: 16,
margin: [ 0, 10, 30, 50 ], margin: [ 20, 20, 10, 10 ],
radius: 10, radius: 0,
highlight: 'rgb(254, 219, 0)' highlight: 'rgb(254, 219, 0)'
}, },
"sub": { "sub": {
stroke: new kity.Pen( "white", 2 ).setLineCap( "round" ).setLineJoin( "round" ), stroke: new kity.Pen( "white", 2 ).setLineCap( "round" ).setLineJoin( "round" ),
color: "white", color: "#333",
fontSize: 12, fontSize: 12,
margin: [ 0, 10, 20, 6 ], margin: [ 10, 10, 10, 30 ],
padding: [ 5, 10, 5.5, 10 ], padding: [ 5, 10, 5.5, 10 ],
highlight: 'rgb(254, 219, 0)' highlight: 'rgb(254, 219, 0)',
fill: 'rgb(231, 243, 255)'
} }
}; };
//更新背景 //更新背景
...@@ -119,9 +110,9 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -119,9 +110,9 @@ KityMinder.registerModule( "LayoutBottom", function () {
Layout.bgShadow.fill( 'black' ).setOpacity( 0.2 ).setRadius( nodeStyle.radius ).translate( 3, 5 ); Layout.bgShadow.fill( 'black' ).setOpacity( 0.2 ).setRadius( nodeStyle.radius ).translate( 3, 5 );
break; break;
case "sub": case "sub":
var underline = Layout.underline = new kity.Path(); var bgRc = node.getBgRc().clear();
var highlightshape = Layout.highlightshape = new kity.Rect().setRadius( 4 ); bgRc.addShape( Layout.bgRect = new kity.Rect() );
node.getBgRc().clear().addShapes( [ Layout.bgRect = new kity.Rect().setRadius( 4 ), highlightshape, underline ] ); Layout.bgRect.fill( nodeStyle.fill );
break; break;
default: default:
break; break;
...@@ -134,6 +125,10 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -134,6 +125,10 @@ KityMinder.registerModule( "LayoutBottom", function () {
var nodeStyle = nodeStyles[ nodeType ]; var nodeStyle = nodeStyles[ nodeType ];
var txtShape = node.getTextShape(); var txtShape = node.getTextShape();
txtShape.fill( nodeStyle.color ).setSize( nodeStyle.fontSize ).setY( -3 ); txtShape.fill( nodeStyle.color ).setSize( nodeStyle.fontSize ).setY( -3 );
if ( nodeType === "main" ) {
var subgroup = Layout.subgroup = new kity.Group();
minder.getRenderContainer().addShape( subgroup );
}
}; };
//根据内容调整节点尺寸 //根据内容调整节点尺寸
var updateShapeByCont = function ( node ) { var updateShapeByCont = function ( node ) {
...@@ -152,18 +147,8 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -152,18 +147,8 @@ KityMinder.registerModule( "LayoutBottom", function () {
Layout.bgShadow.setWidth( width ).setHeight( height ); Layout.bgShadow.setWidth( width ).setHeight( height );
break; break;
case "sub": case "sub":
var _contWidth = contRc.getWidth(); width = _contRCWidth + nodeStyle.padding[ 1 ] + nodeStyle.padding[ 3 ];
var _contHeight = contRc.getHeight(); height = _contRCHeight + nodeStyle.padding[ 0 ] + nodeStyle.padding[ 2 ];
width = _contWidth + nodeStyle.padding[ 1 ] + nodeStyle.padding[ 3 ];
height = _contHeight + nodeStyle.padding[ 0 ] + nodeStyle.padding[ 2 ];
Layout.underline.getDrawer()
.clear()
.moveTo( 0, _contHeight + nodeStyle.padding[ 2 ] + nodeStyle.padding[ 0 ] )
.lineTo( _contWidth + nodeStyle.padding[ 1 ] + nodeStyle.padding[ 3 ], _contHeight + nodeStyle.padding[ 2 ] + nodeStyle.padding[ 0 ] );
Layout.underline.stroke( nodeStyle.stroke );
Layout.highlightshape
.setWidth( _contWidth + nodeStyle.padding[ 1 ] + nodeStyle.padding[ 3 ] )
.setHeight( _contHeight + nodeStyle.padding[ 0 ] + nodeStyle.padding[ 2 ] );
Layout.bgRect.setWidth( width ).setHeight( height ); Layout.bgRect.setWidth( width ).setHeight( height );
break; break;
default: default:
...@@ -171,87 +156,95 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -171,87 +156,95 @@ KityMinder.registerModule( "LayoutBottom", function () {
} }
contRc.setTransform( new kity.Matrix().translate( nodeStyle.padding[ 3 ], nodeStyle.padding[ 0 ] + node.getTextShape().getHeight() ) ); contRc.setTransform( new kity.Matrix().translate( nodeStyle.padding[ 3 ], nodeStyle.padding[ 0 ] + node.getTextShape().getHeight() ) );
}; };
//计算节点在垂直方向的位置 var updateLayoutMain = function () {
var updateLayoutVertical = function ( node ) { var _root = minder.getRoot();
var mainnodes = _root.getChildren();
var countMainWidth = function ( node ) {
var nLayout = node.getLayout();
var selfwidth = node.getRenderContainer().getWidth() + nodeStyles.main.margin[ 1 ] + nodeStyles.main.margin[ 3 ];
var childwidth = nLayout.subgroup.getWidth() + nodeStyles.main.margin[ 1 ] + nodeStyles.sub.margin[ 3 ];
var branchwidth = nLayout.branchwidth = ( selfwidth > childwidth ? selfwidth : childwidth );
return branchwidth;
};
var rootLayout = _root.getLayout();
var rootbranchwidth = 0;
for ( var j = 0; j < mainnodes.length; j++ ) {
rootbranchwidth += countMainWidth( mainnodes[ j ] );
}
var sX = rootLayout.x - rootbranchwidth / 2;
for ( var k = 0; k < mainnodes.length; k++ ) {
var mLayout = mainnodes[ k ].getLayout();
mLayout.x = sX;
sX += mLayout.branchwidth;
}
return mainnodes;
};
var updateLayoutAll = function ( node, parent, action ) {
var effectSet = [];
var nodeType = node.getType(); var nodeType = node.getType();
var parent = node.getParent();
var effectSet = [ node ];
var Layout = node.getLayout(); var Layout = node.getLayout();
var _buffer = [ node ]; var _root = minder.getRoot();
while ( _buffer.length !== 0 ) { var rootLayout = _root.getLayout();
var prt = _buffer[ 0 ].getParent(); if ( nodeType === "root" ) {
_buffer = _buffer.concat( _buffer[ 0 ].getChildren() ); Layout.x = getMinderSize().width / 2;
if ( !prt ) {
Layout.y = 100; Layout.y = 100;
_buffer.shift(); Layout.align = "center";
continue; effectSet.push( node );
}
var parentLayout = prt.getLayout();
var parentHeight = prt.getRenderContainer().getHeight();
var parentStyle = nodeStyles[ prt.getType() ];
var childLayout = _buffer[ 0 ].getLayout();
var childStyle = nodeStyles[ _buffer[ 0 ].getType() ];
childLayout.y = parentLayout.y + parentHeight + parentStyle.margin[ 2 ] + childStyle.margin[ 2 ];
effectSet.push( _buffer[ 0 ] );
_buffer.shift();
}
return effectSet;
};
//计算节点在水平方向的位置
var updateLayoutHorizon = function ( node, parent, action ) {
var root = minder.getRoot();
var effectSet = [ node ];
if ( action === "remove" ) {
effectSet = [];
}
var Layout = node.getLayout();
var nodeShape = node.getRenderContainer();
var nodeType = node.getType();
var nodeStyle = nodeStyles[ nodeType ];
var countBranchWidth = function ( node ) {
var nodeStyle = nodeStyles[ node.getType() ];
var selfWidth = node.getRenderContainer().getWidth() + nodeStyle.margin[ 1 ] + nodeStyle.margin[ 3 ];
var childWidth = ( function () {
var sum = 0;
var children = node.getChildren(); var children = node.getChildren();
for ( var i = 0; i < children.length; i++ ) { for ( var i = 0; i < children.length; i++ ) {
var childLayout = children[ i ].getLayout(); var childLayout = children[ i ].getLayout();
if ( children[ i ].getRenderContainer().getWidth() !== 0 ) childLayout.y = Layout.y + node.getRenderContainer().getHeight() + nodeStyles.root.margin[ 2 ] + nodeStyles.main.margin[ 0 ];
sum += childLayout.branchwidth;
} }
return sum; effectSet = effectSet.concat( children );
} )(); } else if ( nodeType === "main" ) {
return ( selfWidth > childWidth ? selfWidth : childWidth ); Layout.align = "left";
};
if ( nodeType === "root" ) {
Layout.x = getMinderSize().width / 2 - node.getRenderContainer().getWidth() / 2;
effectSet.push( node );
} else {
if ( action === "append" || action === "contract" ) { if ( action === "append" || action === "contract" ) {
Layout.branchwidth = node.getRenderContainer().getWidth() + nodeStyle.margin[ 1 ] + nodeStyle.margin[ 3 ]; Layout.y = rootLayout.y + _root.getRenderContainer().getHeight() + nodeStyles.root.margin[ 2 ] + nodeStyles.main.margin[ 0 ];
} else if ( action === "change" ) {
Layout.branchheight = countBranchWidth( node );
} }
effectSet = updateLayoutMain();
} else {
Layout.align = "left";
var parentLayout = parent.getLayout(); var parentLayout = parent.getLayout();
var parentShape = parent.getRenderContainer(); if ( action === "append" ) {
var prt = node.getParent() || parent; if ( parent.getType() === "main" ) {
//自底向上更新祖先元素的branchwidth值 Layout.x = nodeStyles.sub.margin[ 3 ];
while ( prt ) { } else {
Layout.x = parentLayout.x + nodeStyles.sub.margin[ 3 ];
}
}
if ( action === "append" || action === "contract" ) {
Layout.branchheight = node.getRenderContainer().getHeight() + nodeStyles.sub.margin[ 0 ] + nodeStyles.sub.margin[ 2 ];
}
var prt = parent;
if ( action === "change" ) {
prt = node;
}
//自底向上更新branchheight
while ( prt.getType() !== "main" ) {
var c = prt.getChildren();
var prtLayout = prt.getLayout(); var prtLayout = prt.getLayout();
prtLayout.branchheight = countBranchWidth( prt ); var branchHeight = prt.getRenderContainer().getHeight() + nodeStyles.sub.margin[ 0 ] + nodeStyles.sub.margin[ 2 ];
for ( var i1 = 0; i1 < c.length; i1++ ) {
branchHeight += c[ i1 ].getLayout().branchheight;
}
prtLayout.branchheight = branchHeight;
prt = prt.getParent(); prt = prt.getParent();
} }
//自顶向下更新受影响一侧的y值 //自顶向下更新y
var _buffer = [ root ]; var _buffer = [ prt ];
while ( _buffer.length > 0 ) { while ( _buffer.length !== 0 ) {
var childrenC = _buffer[ 0 ].getChildren();
_buffer = _buffer.concat( childrenC );
var _buffer0Layout = _buffer[ 0 ].getLayout(); var _buffer0Layout = _buffer[ 0 ].getLayout();
var children = _buffer[ 0 ].getChildren(); var _buffer0Style = nodeStyles[ _buffer[ 0 ].getType() ];
_buffer = _buffer.concat( children ); var sY;
var sX = _buffer0Layout.x - _buffer0Layout.branchwidth / 2; if ( _buffer[ 0 ].getType() === "main" ) sY = 0;
for ( var i = 0; i < children.length; i++ ) { else sY = _buffer0Layout.y + _buffer[ 0 ].getRenderContainer().getHeight() + _buffer0Style.margin[ 2 ];
var childLayout = children[ i ].getLayout(); for ( var s = 0; s < childrenC.length; s++ ) {
childLayout.x = sX; var childLayoutC = childrenC[ s ].getLayout();
sX += childLayout.branchwidth; var childStyleC = nodeStyles[ childrenC[ s ].getType() ];
childLayoutC.y = sY + childStyleC.margin[ 0 ];
sY += childLayoutC.branchheight;
} }
effectSet.push( _buffer[ 0 ] ); effectSet.push( _buffer[ 0 ] );
_buffer.shift(); _buffer.shift();
...@@ -265,7 +258,20 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -265,7 +258,20 @@ KityMinder.registerModule( "LayoutBottom", function () {
var align = Layout.align; var align = Layout.align;
var _rectHeight = nodeShape.getHeight(); var _rectHeight = nodeShape.getHeight();
var _rectWidth = nodeShape.getWidth(); var _rectWidth = nodeShape.getWidth();
switch ( align ) {
case "right":
nodeShape.setTransform( new kity.Matrix().translate( Layout.x - _rectWidth, Layout.y ) );
break;
case "center":
nodeShape.setTransform( new kity.Matrix().translate( Layout.x - _rectWidth / 2, Layout.y ) );
break;
default:
nodeShape.setTransform( new kity.Matrix().translate( Layout.x, Layout.y ) ); nodeShape.setTransform( new kity.Matrix().translate( Layout.x, Layout.y ) );
break;
}
if ( node.getType() === "main" ) {
Layout.subgroup.setTransform( new kity.Matrix().translate( Layout.x, Layout.y + node.getRenderContainer().getHeight() ) );
}
node.setPoint( Layout.x, Layout.y ); node.setPoint( Layout.x, Layout.y );
}; };
var updateConnectAndshIcon = function ( node ) { var updateConnectAndshIcon = function ( node ) {
...@@ -273,73 +279,50 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -273,73 +279,50 @@ KityMinder.registerModule( "LayoutBottom", function () {
var Layout = node.getLayout(); var Layout = node.getLayout();
var nodeStyle = nodeStyles[ node.getType() ]; var nodeStyle = nodeStyles[ node.getType() ];
var connect; var connect;
var _root = minder.getRoot();
var _rootLayout = _root.getLayout();
//更新连线 //更新连线
if ( nodeType === "main" ) { if ( nodeType === "main" ) {
if ( !Layout.connect ) { if ( !Layout.connect ) {
connect = Layout.connect = new kity.Group(); connect = Layout.connect = new kity.Path();
var bezier = Layout.connect.bezier = new kity.Bezier();
var circle = Layout.connect.circle = new kity.Circle();
connect.addShapes( [ bezier, circle ] );
minder.getRenderContainer().addShape( connect ); minder.getRenderContainer().addShape( connect );
minder.getRoot().getRenderContainer().bringTop();
} }
var parent = minder.getRoot();
var rootX = parent.getLayout().x;
var rootY = parent.getLayout().y;
connect = Layout.connect; connect = Layout.connect;
var nodeShape = node.getRenderContainer(); var sX = _rootLayout.x;
var nodeClosurePoints = nodeShape.getRenderBox().closurePoints; var sY = _rootLayout.y + _root.getRenderContainer().getHeight();
var sPos; var transX = Layout.x + node.getRenderContainer().getWidth() / 2;
var endPos; var transY = sY + nodeStyles.root.margin[ 2 ];
if ( Layout.appendside === "left" ) { connect.getDrawer().clear()
sPos = new kity.BezierPoint( rootX - 30, nodeClosurePoints[ 2 ].y + nodeShape.getHeight() / 2 ); .moveTo( sX, sY )
endPos = new kity.BezierPoint( nodeClosurePoints[ 2 ].x + 3, nodeClosurePoints[ 2 ].y + nodeShape.getHeight() / 2 ); .lineTo( sX, transY )
} else { .lineTo( transX, transY )
sPos = new kity.BezierPoint( rootX + 30, nodeClosurePoints[ 3 ].y + nodeShape.getHeight() / 2 ); .lineTo( transX, Layout.y );
endPos = new kity.BezierPoint( nodeClosurePoints[ 3 ].x - 3, nodeClosurePoints[ 3 ].y + nodeShape.getHeight() / 2 ); connect.stroke( nodeStyles.main.stroke );
}
var sPosV = sPos.getVertex();
var endPosV = endPos.getVertex();
sPos.setVertex( rootX, rootY );
connect.bezier.setPoints( [ sPos, endPos ] ).stroke( nodeStyle.stroke );
connect.circle.setCenter( endPosV.x + ( Layout.appendside === "left" ? 1 : -1.5 ), endPosV.y ).fill( "white" ).setRadius( 4 );
} else if ( nodeType === "sub" ) { } else if ( nodeType === "sub" ) {
var parent = node.getParent();
var parentLayout = parent.getLayout();
if ( !Layout.connect ) { if ( !Layout.connect ) {
connect = Layout.connect = new kity.Path(); connect = Layout.connect = new kity.Path();
minder.getRenderContainer().addShape( connect ); Layout.subgroup.addShape( connect );
} }
connect = Layout.connect; connect = Layout.connect;
var parentShape = node.getParent().getRenderContainer(); var ssX, ssY;
var parentBox = parentShape.getRenderBox(); if ( parent.getType() === "main" ) {
var parentLayout = node.getParent().getLayout(); ssX = 10;
var parentStyle = nodeStyles[ node.getParent().getType() ]; ssY = 0;
var Shape = node.getRenderContainer();
var sX, sY = parentLayout.y;
var nodeX, nodeY = Shape.getRenderBox().closurePoints[ 1 ].y;
if ( Layout.appendside === "left" ) {
sX = parentBox.closurePoints[ 1 ].x - parentStyle.margin[ 1 ];
nodeX = Shape.getRenderBox().closurePoints[ 0 ].x;
connect.getDrawer()
.clear()
.moveTo( sX, sY )
.lineTo( sX, nodeY > sY ? ( nodeY - nodeStyle.margin[ 3 ] ) : ( nodeY + nodeStyle.margin[ 3 ] ) );
if ( nodeY > sY ) connect.getDrawer().carcTo( nodeStyle.margin[ 3 ], nodeX, nodeY, 0, 1 );
else connect.getDrawer().carcTo( nodeStyle.margin[ 3 ], nodeX, nodeY );
connect.stroke( nodeStyle.stroke );
} else { } else {
sX = parentBox.closurePoints[ 0 ].x + parentStyle.margin[ 1 ]; ssX = parentLayout.x + 10;
nodeX = Shape.getRenderBox().closurePoints[ 1 ].x + 1; ssY = parentLayout.y + parent.getRenderContainer().getHeight() + 10;
connect.getDrawer()
.clear()
.moveTo( sX, sY )
.lineTo( sX, nodeY > sY ? ( nodeY - nodeStyle.margin[ 3 ] ) : ( nodeY + nodeStyle.margin[ 3 ] ) );
if ( nodeY > sY ) connect.getDrawer().carcTo( nodeStyle.margin[ 3 ], nodeX, nodeY );
else connect.getDrawer().carcTo( nodeStyle.margin[ 3 ], nodeX, nodeY, 0, 1 );
connect.stroke( nodeStyle.stroke );
} }
var transsY = Layout.y + node.getRenderContainer().getHeight() / 2;
connect.getDrawer().clear()
.moveTo( ssX, ssY )
.lineTo( ssX, transsY )
.lineTo( Layout.x, transsY );
connect.stroke( nodeStyles.sub.stroke );
} }
//更新收放icon //更新收放icon
if ( nodeType !== "root" ) { if ( nodeType !== "root" && node.getChildren().length !== 0 ) {
if ( !Layout.shicon ) { if ( !Layout.shicon ) {
Layout.shicon = new ShIcon( node ); Layout.shicon = new ShIcon( node );
} }
...@@ -355,21 +338,13 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -355,21 +338,13 @@ KityMinder.registerModule( "LayoutBottom", function () {
switch ( nodeType ) { switch ( nodeType ) {
case "root": case "root":
case "main": case "main":
case "sub":
if ( highlight ) { if ( highlight ) {
Layout.bgRect.fill( nodeStyle.highlight ); Layout.bgRect.fill( nodeStyle.highlight );
} else { } else {
Layout.bgRect.fill( nodeStyle.fill ); Layout.bgRect.fill( nodeStyle.fill );
} }
break; break;
case "sub":
if ( highlight ) {
Layout.highlightshape.fill( nodeStyle.highlight ).setOpacity( 1 );
node.getTextShape().fill( 'black' );
} else {
Layout.highlightshape.setOpacity( 0 );
node.getTextShape().fill( 'white' );
}
break;
default: default:
break; break;
} }
...@@ -383,13 +358,18 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -383,13 +358,18 @@ KityMinder.registerModule( "LayoutBottom", function () {
}, false ) ); }, false ) );
updateShapeByCont( node ); updateShapeByCont( node );
var set1 = updateLayoutHorizon( node ); var set = updateLayoutAll( node, node.getParent(), "change" );
var set2 = updateLayoutVertical( node, node.getParent(), "change" );
var set = uSet( set1, set2 );
for ( var i = 0; i < set.length; i++ ) { for ( var i = 0; i < set.length; i++ ) {
translateNode( set[ i ] ); translateNode( set[ i ] );
updateConnectAndshIcon( set[ i ] ); updateConnectAndshIcon( set[ i ] );
} }
if ( node.getType() === "sub" ) {
var set1 = updateLayoutMain();
for ( var j = 0; j < set1.length; j++ ) {
translateNode( set1[ j ] );
updateConnectAndshIcon( set1[ j ] );
}
}
}, },
initStyle: function () { initStyle: function () {
var _root = minder.getRoot(); var _root = minder.getRoot();
...@@ -405,8 +385,7 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -405,8 +385,7 @@ KityMinder.registerModule( "LayoutBottom", function () {
node: _root node: _root
}, false ) ); }, false ) );
updateShapeByCont( _root ); updateShapeByCont( _root );
updateLayoutHorizon( _root ); updateLayoutAll( _root );
updateLayoutVertical( _root );
translateNode( _root ); translateNode( _root );
var _buffer = [ _root ]; var _buffer = [ _root ];
var _cleanbuffer = []; var _cleanbuffer = [];
...@@ -427,13 +406,22 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -427,13 +406,22 @@ KityMinder.registerModule( "LayoutBottom", function () {
} }
}, },
appendChildNode: function ( parent, node, sibling ) { appendChildNode: function ( parent, node, sibling ) {
minder.handelNodeInsert( node );
node.clearLayout(); node.clearLayout();
var parentLayout = parent.getLayout();
//设置分支类型 //设置分支类型
if ( parent.getType() === "root" ) { if ( parent.getType() === "root" ) {
node.setType( "main" ); node.setType( "main" );
minder.handelNodeInsert( node );
} else { } else {
node.setType( "sub" ); node.setType( "sub" );
//将节点加入到main分支的subgroup中
parentLayout.subgroup.addShape( node.getRenderContainer() );
node.getLayout().subgroup = parentLayout.subgroup;
}
if ( sibling ) {
parent.insertChild( node, sibling.getIndex() + 1 );
} else {
parent.appendChild( node );
} }
//计算位置等流程 //计算位置等流程
updateBg( node ); updateBg( node );
...@@ -445,22 +433,97 @@ KityMinder.registerModule( "LayoutBottom", function () { ...@@ -445,22 +433,97 @@ KityMinder.registerModule( "LayoutBottom", function () {
node: node node: node
}, false ) ); }, false ) );
updateShapeByCont( node ); updateShapeByCont( node );
var set2 = updateLayoutHorizon( node, parent, "append" ); var set = updateLayoutAll( node, parent, "append" );
var set1 = updateLayoutVertical( node );
var set = uSet( set1, set2 );
for ( var i = 0; i < set.length; i++ ) { for ( var i = 0; i < set.length; i++ ) {
translateNode( set[ i ] ); translateNode( set[ i ] );
updateConnectAndshIcon( set[ i ] ); updateConnectAndshIcon( set[ i ] );
} }
if ( node.getType() === "sub" ) {
var set1 = updateLayoutMain();
for ( var j = 0; j < set1.length; j++ ) {
translateNode( set1[ j ] );
updateConnectAndshIcon( set1[ j ] );
}
}
}, },
appendSiblingNode: function ( sibling, node ) { appendSiblingNode: function ( sibling, node ) {
var parent = sibling.getParent();
this.appendChildNode( parent, node, sibling );
}, },
removeNode: function ( nodes ) { removeNode: function ( nodes ) {
while ( nodes.length !== 0 ) {
var parent = nodes[ 0 ].getParent();
if ( !parent ) {
nodes.splice( 0, 1 );
return false;
}
var nodeLayout = nodes[ 0 ].getLayout();
parent.removeChild( nodes[ 0 ] );
var set = updateLayoutAll( nodes[ 0 ], parent, "remove" );
for ( var j = 0; j < set.length; j++ ) {
translateNode( set[ j ] );
updateConnectAndshIcon( set[ j ] );
}
var set1 = updateLayoutMain();
for ( var k = 0; k < set1.length; k++ ) {
translateNode( set1[ k ] );
updateConnectAndshIcon( set1[ k ] );
}
var _buffer = [ nodes[ 0 ] ];
while ( _buffer.length !== 0 ) {
_buffer = _buffer.concat( _buffer[ 0 ].getChildren() );
try {
_buffer[ 0 ].getRenderContainer().remove();
var Layout = _buffer[ 0 ].getLayout();
Layout.connect.remove();
Layout.shicon.remove();
} catch ( error ) {
console.log( "isRemoved" );
}
//检测当前节点是否在选中的数组中,如果在的话,从选中数组中去除
var idx = nodes.indexOf( _buffer[ 0 ] );
if ( idx !== -1 ) {
nodes.splice( idx, 1 );
}
_buffer.shift();
}
}
}, },
expandNode: function ( ico ) { expandNode: function ( ico ) {
var isExpand = ico.icon.switchState();
var node = ico.icon._node;
var _buffer = node.getChildren();
var _cleanbuffer = [];
while ( _buffer.length !== 0 ) {
var Layout = _buffer[ 0 ].getLayout();
if ( isExpand ) {
var parent = _buffer[ 0 ].getParent();
Layout.parent = parent;
_cleanbuffer.push( _buffer[ 0 ] );
Layout.connect = null;
Layout.shicon = null;
} else {
_buffer[ 0 ].getRenderContainer().remove();
Layout.connect.remove();
if ( Layout.shicon ) Layout.shicon.remove();
}
_buffer = _buffer.concat( _buffer[ 0 ].getChildren() );
_buffer.shift();
}
if ( isExpand ) {
node.clearChildren();
for ( var j = 0; j < _cleanbuffer.length; j++ ) {
_cleanbuffer[ j ].clearChildren();
minder.appendChildNode( _cleanbuffer[ j ].getLayout().parent, _cleanbuffer[ j ] );
}
}
var set = [];
if ( !isExpand ) set = updateLayoutAll( node, node.getParent(), "contract" );
for ( var i = 0; i < set.length; i++ ) {
translateNode( set[ i ] );
updateConnectAndshIcon( set[ i ] );
}
} }
}; };
this.addLayoutStyle( "bottom", _style ); this.addLayoutStyle( "bottom", _style );
......
...@@ -605,7 +605,6 @@ KityMinder.registerModule( "LayoutDefault", function () { ...@@ -605,7 +605,6 @@ KityMinder.registerModule( "LayoutDefault", function () {
var parent = _buffer[ 0 ].getParent(); var parent = _buffer[ 0 ].getParent();
Layout.parent = parent; Layout.parent = parent;
_cleanbuffer.push( _buffer[ 0 ] ); _cleanbuffer.push( _buffer[ 0 ] );
//minder.appendChildNode( parent, _buffer[ 0 ] );
Layout.connect = null; Layout.connect = null;
Layout.shicon = null; Layout.shicon = null;
} else { } else {
......
...@@ -8,7 +8,11 @@ KityMinder.registerModule( "LayoutModule", function () { ...@@ -8,7 +8,11 @@ KityMinder.registerModule( "LayoutModule", function () {
return this._layoutStyles[ name ]; return this._layoutStyles[ name ];
}, },
getLayoutStyleItems: function () { getLayoutStyleItems: function () {
return this._layoutStyles; var items = [];
for ( var key in this._layoutStyles ) {
items.push( key );
}
return items;
}, },
getCurrentStyle: function () { getCurrentStyle: function () {
var _root = this.getRoot(); var _root = this.getRoot();
...@@ -90,7 +94,10 @@ KityMinder.registerModule( "LayoutModule", function () { ...@@ -90,7 +94,10 @@ KityMinder.registerModule( "LayoutModule", function () {
var SwitchLayoutCommand = kity.createClass( "SwitchLayoutCommand", ( function () { var SwitchLayoutCommand = kity.createClass( "SwitchLayoutCommand", ( function () {
return { return {
base: Command, base: Command,
execute: switchLayout execute: switchLayout,
queryValue: function ( km ) {
return km.getCurrentStyle();
}
}; };
} )() ); } )() );
var AppendChildNodeCommand = kity.createClass( "AppendChildNodeCommand", ( function () { var AppendChildNodeCommand = kity.createClass( "AppendChildNodeCommand", ( function () {
...@@ -98,12 +105,17 @@ KityMinder.registerModule( "LayoutModule", function () { ...@@ -98,12 +105,17 @@ KityMinder.registerModule( "LayoutModule", function () {
base: Command, base: Command,
execute: function ( km, node ) { execute: function ( km, node ) {
var parent = km.getSelectedNode(); var parent = km.getSelectedNode();
if ( !parent ) {
return false;
}
km.appendChildNode( parent, node ); km.appendChildNode( parent, node );
km.select( node, true ); km.select( node, true );
return node; return node;
},
queryState: function ( km ) {
var selectedNode = km.getSelectedNode();
if ( !selectedNode ) {
return -1;
} else {
return 0;
}
} }
}; };
} )() ); } )() );
...@@ -112,9 +124,6 @@ KityMinder.registerModule( "LayoutModule", function () { ...@@ -112,9 +124,6 @@ KityMinder.registerModule( "LayoutModule", function () {
base: Command, base: Command,
execute: function ( km, node ) { execute: function ( km, node ) {
var selectedNode = km.getSelectedNode(); var selectedNode = km.getSelectedNode();
if ( !selectedNode ) {
return false;
}
if ( selectedNode.isRoot() ) { if ( selectedNode.isRoot() ) {
node.setType( "main" ); node.setType( "main" );
km.appendChildNode( selectedNode, node ); km.appendChildNode( selectedNode, node );
...@@ -124,6 +133,15 @@ KityMinder.registerModule( "LayoutModule", function () { ...@@ -124,6 +133,15 @@ KityMinder.registerModule( "LayoutModule", function () {
} }
km.select( node, true ); km.select( node, true );
return node; return node;
},
queryState: function ( km ) {
var selectedNodes = km.getSelectedNodes();
//没选中节点和单选root的时候返回不可执行
if ( selectedNodes.length === 0 || ( selectedNodes.length === 1 && selectedNodes[ 0 ] === km.getRoot() ) ) {
return -1;
} else {
return 0;
}
} }
}; };
} )() ); } )() );
...@@ -133,10 +151,6 @@ KityMinder.registerModule( "LayoutModule", function () { ...@@ -133,10 +151,6 @@ KityMinder.registerModule( "LayoutModule", function () {
execute: function ( km ) { execute: function ( km ) {
var selectedNodes = km.getSelectedNodes(); var selectedNodes = km.getSelectedNodes();
var _root = km.getRoot(); var _root = km.getRoot();
if ( selectedNodes.length === 0 || ( selectedNodes.length === 1 && !selectedNodes[ 0 ].getParent() ) ) {
km.select( _root );
return false;
}
var _buffer = []; var _buffer = [];
for ( var i = 0; i < selectedNodes.length; i++ ) { for ( var i = 0; i < selectedNodes.length; i++ ) {
_buffer.push( selectedNodes[ i ] ); _buffer.push( selectedNodes[ i ] );
...@@ -148,6 +162,14 @@ KityMinder.registerModule( "LayoutModule", function () { ...@@ -148,6 +162,14 @@ KityMinder.registerModule( "LayoutModule", function () {
} while ( _buffer.length > 1 ); } while ( _buffer.length > 1 );
km.removeNode( selectedNodes ); km.removeNode( selectedNodes );
km.select( _buffer[ 0 ] ); km.select( _buffer[ 0 ] );
},
queryState: function ( km ) {
var selectedNodes = km.getSelectedNodes();
if ( selectedNodes.length === 0 || ( selectedNodes.length === 1 && selectedNodes[ 0 ] === km.getRoot() ) ) {
return -1;
} else {
return 0;
}
} }
}; };
} )() ); } )() );
...@@ -181,7 +203,12 @@ KityMinder.registerModule( "LayoutModule", function () { ...@@ -181,7 +203,12 @@ KityMinder.registerModule( "LayoutModule", function () {
} }
}, },
"defaultOptions": { "defaultOptions": {
"defaultlayoutstyle": "default" "defaultlayoutstyle": "default",
"node": {
'appendsiblingnode': 'appendsiblingnode',
'appendchildnode': 'appendchildnode',
'removenode': 'removenode'
}
} }
}; };
} ); } );
\ No newline at end of file
...@@ -29,7 +29,9 @@ KityMinder.registerModule( "Select", function () { ...@@ -29,7 +29,9 @@ KityMinder.registerModule( "Select", function () {
startPosition = g.snapToSharp( e.getPosition() ); startPosition = g.snapToSharp( e.getPosition() );
}, },
selectMove: function ( e ) { selectMove: function ( e ) {
if ( minder.isTextEditStatus() ) {
return;
}
if ( !startPosition ) return; if ( !startPosition ) return;
var p1 = startPosition, var p1 = startPosition,
...@@ -65,7 +67,7 @@ KityMinder.registerModule( "Select", function () { ...@@ -65,7 +67,7 @@ KityMinder.registerModule( "Select", function () {
// 计算选中范围 // 计算选中范围
minder.getRoot().traverse( function ( node ) { minder.getRoot().traverse( function ( node ) {
var renderBox = node.getRenderContainer().getRenderBox(); var renderBox = node.getRenderContainer().getRenderBox( "top" );
if ( g.isBoxIntersect( renderBox, marquee ) ) { if ( g.isBoxIntersect( renderBox, marquee ) ) {
selectedNodes.push( node ); selectedNodes.push( node );
} }
...@@ -80,7 +82,7 @@ KityMinder.registerModule( "Select", function () { ...@@ -80,7 +82,7 @@ KityMinder.registerModule( "Select", function () {
} }
if ( marqueeMode ) { if ( marqueeMode ) {
marqueeShape.fadeOut( 200, 'ease', 0, function () { marqueeShape.fadeOut( 200, 'ease', 0, function () {
if(marqueeShape.remove) marqueeShape.remove(); if ( marqueeShape.remove ) marqueeShape.remove();
} ); } );
marqueeMode = false; marqueeMode = false;
} }
......
...@@ -62,7 +62,7 @@ KityMinder.registerModule( 'Zoom', function () { ...@@ -62,7 +62,7 @@ KityMinder.registerModule( 'Zoom', function () {
'zoom-out': ZoomOutCommand 'zoom-out': ZoomOutCommand
}, },
addShortcutKeys: { addShortcutKeys: {
"zoom-in": "+", //= "zoom-in": "=", //=
"zoom-out": "-" //- "zoom-out": "-" //-
}, },
events: { events: {
......
KityMinder.registerProtocal( "png", function () {
var LINE_ENDING = '\n',
TAB_CHAR = '\t';
function repeat( s, n ) {
var result = "";
while ( n-- ) result += s;
return result;
}
function encode( json, level ) {
var local = "";
level = level || 0;
local += repeat( TAB_CHAR, level );
local += json.data.text + LINE_ENDING;
if ( json.children ) {
json.children.forEach( function ( child ) {
local += encode( child, level + 1 );
} );
}
return local;
}
function isEmpty( line ) {
return !/\S/.test( line );
}
function getLevel( line ) {
var level = 0;
while ( line.charAt( level ) === TAB_CHAR ) level++;
return level;
}
function getNode( line ) {
return {
data: {
text: line.replace( new RegExp( '^' + TAB_CHAR + '*' ), '' )
}
};
}
function decode( local ) {
var json,
parentMap = {},
lines = local.split( LINE_ENDING ),
line, level, node;
function addChild( parent, child ) {
var children = parent.children || ( parent.children = [] );
children.push( child );
}
for ( var i = 0; i < lines.length; i++ ) {
line = lines[ i ];
if ( isEmpty( line ) ) continue;
level = getLevel( line );
node = getNode( line );
if ( level === 0 ) {
if ( json ) {
throw new Error( 'Invalid local format' );
}
json = node;
} else {
if ( !parentMap[ level - 1 ] ) {
throw new Error( 'Invalid local format' );
}
addChild( parentMap[ level - 1 ], node );
}
parentMap[ level ] = node;
}
return json;
}
var lastTry, lastResult;
function recognize( local ) {
if ( !Utils.isString( local ) ) return false;
lastTry = local;
try {
lastResult = decode( local );
} catch ( e ) {
lastResult = null;
}
return !!lastResult;
}
return {
fileDescription: 'png',
fileExtension: '.png',
encode: function ( json ) {
return encode( json, 0 );
},
decode: function ( local ) {
if ( lastTry == local && lastResult ) {
return lastResult;
}
return decode( local );
},
recognize: recognize,
recognizePriority: -1
};
} );
\ No newline at end of file
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
"<%if(autoRecord) {%>" + "<%if(autoRecord) {%>" +
"<%for( var i=0, len = recordStack.length; i<len; i++ ) {%>" + "<%for( var i=0, len = recordStack.length; i<len; i++ ) {%>" +
"<%var index = recordStack[i];%>" + "<%var index = recordStack[i];%>" +
"<li class=\"<%=itemClassName%><%if( selected == index ) {%> kmui-combobox-checked<%}%>\" data-item-index=\"<%=index%>\" unselectable=\"on\" onmousedown=\"return false\">" + "<li class=\"<%=itemClassName%><%if( selected == index ) {%> kmui-combobox-checked<%}%><%if( disabled[ index ] === true ) {%> kmui-combobox-item-disabled<%}%>\" data-item-index=\"<%=index%>\" unselectable=\"on\" onmousedown=\"return false\">" +
"<span class=\"kmui-combobox-icon\" unselectable=\"on\" onmousedown=\"return false\"></span>" + "<span class=\"kmui-combobox-icon\" unselectable=\"on\" onmousedown=\"return false\"></span>" +
"<label class=\"<%=labelClassName%>\" style=\"<%=itemStyles[ index ]%>\" unselectable=\"on\" onmousedown=\"return false\"><%=items[index]%></label>" + "<label class=\"<%=labelClassName%>\" style=\"<%=itemStyles[ index ]%>\" unselectable=\"on\" onmousedown=\"return false\"><%=items[index]%></label>" +
"</li>" + "</li>" +
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
"<%}%>" + "<%}%>" +
"<%}%>" + "<%}%>" +
"<%for( var i=0, label; label = items[i]; i++ ) {%>" + "<%for( var i=0, label; label = items[i]; i++ ) {%>" +
"<li class=\"<%=itemClassName%><%if( selected == i ) {%> kmui-combobox-checked<%}%> kmui-combobox-item-<%=i%>\" data-item-index=\"<%=i%>\" unselectable=\"on\" onmousedown=\"return false\">" + "<li class=\"<%=itemClassName%><%if( selected == i ) {%> kmui-combobox-checked<%}%> kmui-combobox-item-<%=i%><%if( disabled[ i ] === true ) {%> kmui-combobox-item-disabled<%}%>\" data-item-index=\"<%=i%>\" unselectable=\"on\" onmousedown=\"return false\">" +
"<span class=\"kmui-combobox-icon\" unselectable=\"on\" onmousedown=\"return false\"></span>" + "<span class=\"kmui-combobox-icon\" unselectable=\"on\" onmousedown=\"return false\"></span>" +
"<label class=\"<%=labelClassName%>\" style=\"<%=itemStyles[ i ]%>\" unselectable=\"on\" onmousedown=\"return false\"><%=label%></label>" + "<label class=\"<%=labelClassName%>\" style=\"<%=itemStyles[ i ]%>\" unselectable=\"on\" onmousedown=\"return false\"><%=label%></label>" +
"</li>" + "</li>" +
...@@ -46,10 +46,13 @@ ...@@ -46,10 +46,13 @@
value: [], value: [],
comboboxName: '', comboboxName: '',
selected: '', selected: '',
//初始禁用状态
disabled: {},
//自动记录 //自动记录
autoRecord: true, autoRecord: true,
//最多记录条数 //最多记录条数
recordCount: 5 recordCount: 5,
enabledRecord:true
}, },
init: function( options ){ init: function( options ){
...@@ -87,6 +90,7 @@ ...@@ -87,6 +90,7 @@
initSelectItem: function(){ initSelectItem: function(){
var me = this, var me = this,
options = me.data( "options" ),
labelClass = "."+labelClassName; labelClass = "."+labelClassName;
me.root().delegate('.' + itemClassName, 'click', function(){ me.root().delegate('.' + itemClassName, 'click', function(){
...@@ -94,6 +98,10 @@ ...@@ -94,6 +98,10 @@
var $li = $(this), var $li = $(this),
index = $li.attr('data-item-index'); index = $li.attr('data-item-index');
if ( options.disabled[ index ] ) {
return false;
}
me.trigger('comboboxselect', { me.trigger('comboboxselect', {
index: index, index: index,
label: $li.find(labelClass).text(), label: $li.find(labelClass).text(),
...@@ -126,11 +134,18 @@ ...@@ -126,11 +134,18 @@
*/ */
select: function( index ){ select: function( index ){
var itemCount = this.data('options').itemCount,
items = this.data('options').autowidthitem; var options = this.data( 'options' ),
itemCount = options.itemCount,
items = options.autowidthitem;
if ( items && !items.length ) { if ( items && !items.length ) {
items = this.data('options').items; items = options.items;
}
// 禁用
if ( options.disabled[ index ] ) {
return null;
} }
if( itemCount == 0 ) { if( itemCount == 0 ) {
...@@ -149,6 +164,7 @@ ...@@ -149,6 +164,7 @@
this.trigger( 'changebefore', items[ index ] ); this.trigger( 'changebefore', items[ index ] );
this._update( index ); this._update( index );
this.trigger( 'changeafter', items[ index ] ); this.trigger( 'changeafter', items[ index ] );
...@@ -178,6 +194,65 @@ ...@@ -178,6 +194,65 @@
} ); } );
}, },
getItems: function () {
return this.data( "options" ).items;
},
traverseItems:function(fn){
var values = this.data('options').value;
var labels = this.data('options').items;
$.each(labels,function(i,label){
fn(label,values[i])
});
return this;
},
getItemMapping: function () {
return this.data( "options" ).itemMapping;
},
disableItemByIndex: function ( index ) {
var options = this.data( "options" );
options.disabled[ index ] = true;
this._repaint();
},
disableItemByLabel: function ( label ) {
var itemMapping = this.data('options').itemMapping,
index = itemMapping[ label ];
if ( typeof index === "number" ) {
return this.disableItemByIndex( index );
}
return false;
},
enableItemByIndex: function ( index ) {
var options = this.data( "options" );
delete options.disabled[ index ];
this._repaint();
},
enableItemByLabel: function ( label ) {
var itemMapping = this.data('options').itemMapping,
index = itemMapping[ label ];
if ( typeof index === "number" ) {
return this.enableItemByIndex( index );
}
return false;
},
/** /**
* 转换记录栈 * 转换记录栈
*/ */
...@@ -256,9 +331,9 @@ ...@@ -256,9 +331,9 @@
_update: function ( index ) { _update: function ( index ) {
var options = this.data("options"), var options = this.data("options"),
newStack = [], newStack = [];
newChilds = null;
if(this.data('options').enabledRecord){
$.each( options.recordStack, function( i, item ){ $.each( options.recordStack, function( i, item ){
if( item != index ) { if( item != index ) {
...@@ -275,15 +350,24 @@ ...@@ -275,15 +350,24 @@
} }
options.recordStack = newStack; options.recordStack = newStack;
}
options.selected = index; options.selected = index;
newChilds = $( $.parseTmpl( this.tpl, options ) ); this._repaint();
newStack = null;
},
_repaint: function () {
var newChilds = $( $.parseTmpl( this.tpl, this.data("options") ) );
//重新渲染 //重新渲染
this.root().html( newChilds.html() ); this.root().html( newChilds.html() );
newChilds = null; newChilds = null;
newStack = null;
} }
}; };
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
.kmui-combobox-menu .kmui-combobox-item { .kmui-combobox-menu .kmui-combobox-item {
display: block; display: block;
border: 1px solid white; border: 1px solid white;
white-space:nowrap;
} }
.kmui-combobox-menu .kmui-combobox-item-label { .kmui-combobox-menu .kmui-combobox-item-label {
...@@ -185,3 +186,12 @@ ...@@ -185,3 +186,12 @@
.kmui-combobox-paragraph .kmui-combobox-item-6 .kmui-combobox-item-label { .kmui-combobox-paragraph .kmui-combobox-item-6 .kmui-combobox-item-label {
font-size: 12px; font-size: 12px;
} }
.kmui-combobox-menu .kmui-combobox-item-disabled {
opacity: 0.3;
}
.kmui-combobox-menu .kmui-combobox-item-disabled:HOVER {
border-color: #fff;
background-color: #fff;
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment