Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
K
kityminder-core
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
吴志俊
kityminder-core
Commits
6b25e103
Commit
6b25e103
authored
Feb 24, 2014
by
techird
Browse files
Options
Browse Files
Download
Plain Diff
merge
parents
71e6130a
a65a0432
Changes
31
Show whitespace changes
Inline
Side-by-side
Showing
31 changed files
with
1799 additions
and
1128 deletions
+1799
-1128
.jshintrc
.jshintrc
+2
-1
configure.js
configure.js
+15
-15
dev.js
dist/dev.js
+829
-306
dev.php
dist/dev.php
+3
-0
kity
kity
+1
-1
Actual.xml
kityminder计划.oplx/Actual.xml
+0
-174
__TOC.xml
kityminder计划.oplx/__TOC.xml
+0
-224
__changelog.xml
kityminder计划.oplx/__changelog.xml
+0
-104
zh-cn.js
lang/zh-cn/zh-cn.js
+9
-2
交互点说明.md
spec/交互点说明.md
+109
-0
combobox.js
src/adapter/combobox.js
+8
-28
layout.js
src/adapter/layout.js
+46
-0
node.js
src/adapter/node.js
+67
-0
saveto.js
src/adapter/saveto.js
+49
-1
keymap.js
src/core/keymap.js
+10
-1
minder.js
src/core/minder.js
+42
-14
basestyle.js
src/module/basestyle.js
+2
-2
dragtree.js
src/module/dragtree.js
+21
-4
editor.js
src/module/editor.js
+40
-9
editor.range.js
src/module/editor.range.js
+6
-1
editor.receiver.js
src/module/editor.receiver.js
+8
-3
editor.selection.js
src/module/editor.selection.js
+15
-8
history.js
src/module/history.js
+2
-2
layout.bottom.js
src/module/layout.bottom.js
+252
-189
layout.default.js
src/module/layout.default.js
+0
-1
layout.js
src/module/layout.js
+40
-13
select.js
src/module/select.js
+6
-4
zoom.js
src/module/zoom.js
+1
-1
png.js
src/protocal/png.js
+102
-0
combobox.js
src/ui/combobox.js
+104
-20
comboboxmenu.css
themes/default/css/comboboxmenu.css
+10
-0
No files found.
.jshintrc
View file @
6b25e103
...
...
@@ -23,6 +23,7 @@
"utils",
"$",
"KM",
"keymap"
"keymap",
"baidu"
]
}
\ No newline at end of file
configure.js
View file @
6b25e103
(
function
()
{
function
getKMBasePath
(
docUrl
,
confUrl
)
{
(
function
()
{
function
getKMBasePath
(
docUrl
,
confUrl
)
{
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
;
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
;
...
...
@@ -34,15 +34,15 @@
}
function
optimizationPath
(
path
)
{
function
optimizationPath
(
path
)
{
var
protocol
=
/^
[
a-z
]
+:
\/\/
/
.
exec
(
path
)[
0
],
tmp
=
null
,
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
]
=
""
;
...
...
@@ -63,7 +63,7 @@
'KITYMINDER_HOME_URL'
:
getKMBasePath
(),
//定义工具栏
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 @@
//设置km整体的z-index大小
//,zIndex : 1000
};
})()
}
)()
\ No newline at end of file
dist/dev.js
View file @
6b25e103
...
...
@@ -827,6 +827,9 @@ var Minder = KityMinder.Minder = kity.createClass( "KityMinder", {
this
.
_shortcutkeys
=
{};
this
.
_bindshortcutKeys
();
},
isTextEditStatus
:
function
(){
return
false
;
},
addShortcutKeys
:
function
(
cmd
,
keys
)
{
var
obj
=
{},
km
=
this
;
if
(
keys
)
{
...
...
@@ -845,25 +848,50 @@ var Minder = KityMinder.Minder = kity.createClass( "KityMinder", {
_bindshortcutKeys
:
function
()
{
var
me
=
this
,
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
keyCode
=
originEvent
.
keyCode
||
originEvent
.
which
;
for
(
var
i
in
shortcutkeys
)
{
var
tmp
=
shortcutkeys
[
i
].
split
(
','
);
for
(
var
t
=
0
,
ti
;
ti
=
tmp
[
t
++
];
)
{
ti
=
ti
.
split
(
':'
);
var
key
=
ti
[
0
],
param
=
ti
[
1
];
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
();
var
keys
=
shortcutkeys
[
i
].
toLowerCase
().
split
(
'+'
);
var
current
=
0
;
utils
.
each
(
keys
,
function
(
i
,
k
){
if
(
checkkey
(
k
,
keyCode
,
originEvent
)){
current
++
;
}
});
//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 = {
'NumLock'
:
144
,
'Cmd'
:
91
'Cmd'
:
91
,
'='
:
187
,
'-'
:
189
,
"b"
:
66
,
'i'
:
73
,
'z'
:
90
,
'y'
:
89
};
//添加多语言模块
...
...
@@ -1600,8 +1637,8 @@ KityMinder.registerModule( "HistoryModule", function () {
}
)
},
addShortcutKeys
:
{
"Undo"
:
"ctrl+
90
"
,
//undo
"Redo"
:
"ctrl+
89
"
//redo
"Undo"
:
"ctrl+
z
"
,
//undo
"Redo"
:
"ctrl+
y
"
//redo
},
"events"
:
{
"saveScene"
:
function
(
e
)
{
...
...
@@ -1769,7 +1806,11 @@ KityMinder.registerModule( "LayoutModule", function () {
return
this
.
_layoutStyles
[
name
];
},
getLayoutStyleItems
:
function
()
{
return
this
.
_layoutStyles
;
var
items
=
[];
for
(
var
key
in
this
.
_layoutStyles
)
{
items
.
push
(
key
);
}
return
items
;
},
getCurrentStyle
:
function
()
{
var
_root
=
this
.
getRoot
();
...
...
@@ -1851,7 +1892,10 @@ KityMinder.registerModule( "LayoutModule", function () {
var
SwitchLayoutCommand
=
kity
.
createClass
(
"SwitchLayoutCommand"
,
(
function
()
{
return
{
base
:
Command
,
execute
:
switchLayout
execute
:
switchLayout
,
queryValue
:
function
(
km
)
{
return
km
.
getCurrentStyle
();
}
};
}
)()
);
var
AppendChildNodeCommand
=
kity
.
createClass
(
"AppendChildNodeCommand"
,
(
function
()
{
...
...
@@ -1859,12 +1903,17 @@ KityMinder.registerModule( "LayoutModule", function () {
base
:
Command
,
execute
:
function
(
km
,
node
)
{
var
parent
=
km
.
getSelectedNode
();
if
(
!
parent
)
{
return
false
;
}
km
.
appendChildNode
(
parent
,
node
);
km
.
select
(
node
,
true
);
return
node
;
},
queryState
:
function
(
km
)
{
var
selectedNode
=
km
.
getSelectedNode
();
if
(
!
selectedNode
)
{
return
-
1
;
}
else
{
return
0
;
}
}
};
}
)()
);
...
...
@@ -1873,9 +1922,6 @@ KityMinder.registerModule( "LayoutModule", function () {
base
:
Command
,
execute
:
function
(
km
,
node
)
{
var
selectedNode
=
km
.
getSelectedNode
();
if
(
!
selectedNode
)
{
return
false
;
}
if
(
selectedNode
.
isRoot
()
)
{
node
.
setType
(
"main"
);
km
.
appendChildNode
(
selectedNode
,
node
);
...
...
@@ -1885,6 +1931,15 @@ KityMinder.registerModule( "LayoutModule", function () {
}
km
.
select
(
node
,
true
);
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 () {
execute
:
function
(
km
)
{
var
selectedNodes
=
km
.
getSelectedNodes
();
var
_root
=
km
.
getRoot
();
if
(
selectedNodes
.
length
===
0
||
(
selectedNodes
.
length
===
1
&&
!
selectedNodes
[
0
].
getParent
()
)
)
{
km
.
select
(
_root
);
return
false
;
}
var
_buffer
=
[];
for
(
var
i
=
0
;
i
<
selectedNodes
.
length
;
i
++
)
{
_buffer
.
push
(
selectedNodes
[
i
]
);
...
...
@@ -1909,6 +1960,14 @@ KityMinder.registerModule( "LayoutModule", function () {
}
while
(
_buffer
.
length
>
1
);
km
.
removeNode
(
selectedNodes
);
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 () {
}
},
"defaultOptions"
:
{
"defaultlayoutstyle"
:
"default"
"defaultlayoutstyle"
:
"default"
,
"node"
:
{
'appendsiblingnode'
:
'appendsiblingnode'
,
'appendchildnode'
:
'appendchildnode'
,
'removenode'
:
'removenode'
}
}
};
}
);
...
...
@@ -2554,7 +2618,6 @@ KityMinder.registerModule( "LayoutDefault", function () {
var
parent
=
_buffer
[
0
].
getParent
();
Layout
.
parent
=
parent
;
_cleanbuffer
.
push
(
_buffer
[
0
]
);
//minder.appendChildNode( parent, _buffer[ 0 ] );
Layout
.
connect
=
null
;
Layout
.
shicon
=
null
;
}
else
{
...
...
@@ -2603,21 +2666,24 @@ KityMinder.registerModule( "LayoutBottom", function () {
var
iconShape
=
this
.
shape
=
new
kity
.
Group
();
iconShape
.
class
=
"shicon"
;
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
();
plus
.
getDrawer
()
.
moveTo
(
-
3
,
0
)
.
lineTo
(
3
,
0
)
.
moveTo
(
0
,
-
3
)
.
lineTo
(
0
,
3
);
.
moveTo
(
2
,
5
)
.
lineTo
(
8
,
5
)
.
moveTo
(
5
,
2
)
.
lineTo
(
5
,
8
);
plus
.
stroke
(
"gray"
);
var
dec
=
this
.
_dec
=
new
kity
.
Path
();
dec
.
getDrawer
()
.
moveTo
(
-
3
,
0
)
.
lineTo
(
3
,
0
);
.
moveTo
(
2
,
5
)
.
lineTo
(
8
,
5
);
dec
.
stroke
(
"gray"
);
minder
.
getRenderContainer
().
addShape
(
iconShape
);
iconShape
.
addShapes
(
[
circle
,
plus
,
dec
]
);
if
(
node
.
getType
()
===
"main"
)
minder
.
getRenderContainer
().
addShape
(
iconShape
);
else
{
node
.
getLayout
().
subgroup
.
addShape
(
iconShape
);
}
iconShape
.
addShapes
(
[
rect
,
plus
,
dec
]
);
this
.
update
();
this
.
switchState
();
},
...
...
@@ -2637,12 +2703,9 @@ KityMinder.registerModule( "LayoutBottom", function () {
var
node
=
this
.
_node
;
var
Layout
=
node
.
getLayout
();
var
nodeShape
=
node
.
getRenderContainer
();
var
nodeX
,
nodeY
=
(
node
.
getType
()
===
"main"
?
Layout
.
y
:
(
Layout
.
y
+
nodeShape
.
getHeight
()
/
2
-
5
)
);
if
(
Layout
.
appendside
===
"left"
)
{
nodeX
=
nodeShape
.
getRenderBox
().
closurePoints
[
1
].
x
-
6
;
}
else
{
nodeX
=
nodeShape
.
getRenderBox
().
closurePoints
[
0
].
x
+
6
;
}
var
nodeType
=
node
.
getType
();
var
nodeX
=
nodeShape
.
getRenderBox
().
closurePoints
[
1
].
x
+
5
;
var
nodeY
=
nodeShape
.
getRenderBox
().
closurePoints
[
0
].
y
;
this
.
shape
.
setTransform
(
new
kity
.
Matrix
().
translate
(
nodeX
,
nodeY
)
);
},
remove
:
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
=
{
"root"
:
{
...
...
@@ -2667,8 +2720,8 @@ KityMinder.registerModule( "LayoutBottom", function () {
fill
:
'#e9df98'
,
fontSize
:
24
,
padding
:
[
15.5
,
25.5
,
15.5
,
25.5
],
margin
:
[
0
,
0
,
0
,
0
],
radius
:
3
0
,
margin
:
[
0
,
0
,
2
0
,
0
],
radius
:
0
,
highlight
:
'rgb(254, 219, 0)'
},
"main"
:
{
...
...
@@ -2677,17 +2730,18 @@ KityMinder.registerModule( "LayoutBottom", function () {
color
:
"#333"
,
padding
:
[
6.5
,
20
,
6.5
,
20
],
fontSize
:
16
,
margin
:
[
0
,
10
,
30
,
5
0
],
radius
:
1
0
,
margin
:
[
20
,
20
,
10
,
1
0
],
radius
:
0
,
highlight
:
'rgb(254, 219, 0)'
},
"sub"
:
{
stroke
:
new
kity
.
Pen
(
"white"
,
2
).
setLineCap
(
"round"
).
setLineJoin
(
"round"
),
color
:
"
white
"
,
color
:
"
#333
"
,
fontSize
:
12
,
margin
:
[
0
,
10
,
20
,
6
],
margin
:
[
10
,
10
,
10
,
30
],
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 () {
Layout
.
bgShadow
.
fill
(
'black'
).
setOpacity
(
0.2
).
setRadius
(
nodeStyle
.
radius
).
translate
(
3
,
5
);
break
;
case
"sub"
:
var
underline
=
Layout
.
underline
=
new
kity
.
Path
();
var
highlightshape
=
Layout
.
highlightshape
=
new
kity
.
Rect
().
setRadius
(
4
);
node
.
getBgRc
().
clear
().
addShapes
(
[
Layout
.
bgRect
=
new
kity
.
Rect
().
setRadius
(
4
),
highlightshape
,
underline
]
);
var
bgRc
=
node
.
getBgRc
().
clear
();
bgRc
.
addShape
(
Layout
.
bgRect
=
new
kity
.
Rect
()
);
Layout
.
bgRect
.
fill
(
nodeStyle
.
fill
);
break
;
default
:
break
;
...
...
@@ -2720,6 +2774,10 @@ KityMinder.registerModule( "LayoutBottom", function () {
var
nodeStyle
=
nodeStyles
[
nodeType
];
var
txtShape
=
node
.
getTextShape
();
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
)
{
...
...
@@ -2738,18 +2796,8 @@ KityMinder.registerModule( "LayoutBottom", function () {
Layout
.
bgShadow
.
setWidth
(
width
).
setHeight
(
height
);
break
;
case
"sub"
:
var
_contWidth
=
contRc
.
getWidth
();
var
_contHeight
=
contRc
.
getHeight
();
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
]
);
width
=
_contRCWidth
+
nodeStyle
.
padding
[
1
]
+
nodeStyle
.
padding
[
3
];
height
=
_contRCHeight
+
nodeStyle
.
padding
[
0
]
+
nodeStyle
.
padding
[
2
];
Layout
.
bgRect
.
setWidth
(
width
).
setHeight
(
height
);
break
;
default
:
...
...
@@ -2757,87 +2805,95 @@ KityMinder.registerModule( "LayoutBottom", function () {
}
contRc
.
setTransform
(
new
kity
.
Matrix
().
translate
(
nodeStyle
.
padding
[
3
],
nodeStyle
.
padding
[
0
]
+
node
.
getTextShape
().
getHeight
()
)
);
};
//计算节点在垂直方向的位置
var
updateLayoutVertical
=
function
(
node
)
{
var
updateLayoutMain
=
function
()
{
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
parent
=
node
.
getParent
();
var
effectSet
=
[
node
];
var
Layout
=
node
.
getLayout
();
var
_buffer
=
[
node
];
while
(
_buffer
.
length
!==
0
)
{
var
prt
=
_buffer
[
0
].
getParent
();
_buffer
=
_buffer
.
concat
(
_buffer
[
0
].
getChildren
()
);
if
(
!
prt
)
{
var
_root
=
minder
.
getRoot
();
var
rootLayout
=
_root
.
getLayout
();
if
(
nodeType
===
"root"
)
{
Layout
.
x
=
getMinderSize
().
width
/
2
;
Layout
.
y
=
100
;
_buffer
.
shift
();
continue
;
}
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
;
Layout
.
align
=
"center"
;
effectSet
.
push
(
node
);
var
children
=
node
.
getChildren
();
for
(
var
i
=
0
;
i
<
children
.
length
;
i
++
)
{
var
childLayout
=
children
[
i
].
getLayout
();
if
(
children
[
i
].
getRenderContainer
().
getWidth
()
!==
0
)
sum
+=
childLayout
.
branchwidth
;
childLayout
.
y
=
Layout
.
y
+
node
.
getRenderContainer
().
getHeight
()
+
nodeStyles
.
root
.
margin
[
2
]
+
nodeStyles
.
main
.
margin
[
0
];
}
return
sum
;
}
)();
return
(
selfWidth
>
childWidth
?
selfWidth
:
childWidth
);
};
if
(
nodeType
===
"root"
)
{
Layout
.
x
=
getMinderSize
().
width
/
2
-
node
.
getRenderContainer
().
getWidth
()
/
2
;
effectSet
.
push
(
node
);
}
else
{
effectSet
=
effectSet
.
concat
(
children
);
}
else
if
(
nodeType
===
"main"
)
{
Layout
.
align
=
"left"
;
if
(
action
===
"append"
||
action
===
"contract"
)
{
Layout
.
branchwidth
=
node
.
getRenderContainer
().
getWidth
()
+
nodeStyle
.
margin
[
1
]
+
nodeStyle
.
margin
[
3
];
}
else
if
(
action
===
"change"
)
{
Layout
.
branchheight
=
countBranchWidth
(
node
);
Layout
.
y
=
rootLayout
.
y
+
_root
.
getRenderContainer
().
getHeight
()
+
nodeStyles
.
root
.
margin
[
2
]
+
nodeStyles
.
main
.
margin
[
0
];
}
effectSet
=
updateLayoutMain
();
}
else
{
Layout
.
align
=
"left"
;
var
parentLayout
=
parent
.
getLayout
();
var
parentShape
=
parent
.
getRenderContainer
();
var
prt
=
node
.
getParent
()
||
parent
;
//自底向上更新祖先元素的branchwidth值
while
(
prt
)
{
if
(
action
===
"append"
)
{
if
(
parent
.
getType
()
===
"main"
)
{
Layout
.
x
=
nodeStyles
.
sub
.
margin
[
3
];
}
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
();
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
();
}
//自顶向下更新受影响一侧的y值
var
_buffer
=
[
root
];
while
(
_buffer
.
length
>
0
)
{
//自顶向下更新y
var
_buffer
=
[
prt
];
while
(
_buffer
.
length
!==
0
)
{
var
childrenC
=
_buffer
[
0
].
getChildren
();
_buffer
=
_buffer
.
concat
(
childrenC
);
var
_buffer0Layout
=
_buffer
[
0
].
getLayout
();
var
children
=
_buffer
[
0
].
getChildren
();
_buffer
=
_buffer
.
concat
(
children
);
var
sX
=
_buffer0Layout
.
x
-
_buffer0Layout
.
branchwidth
/
2
;
for
(
var
i
=
0
;
i
<
children
.
length
;
i
++
)
{
var
childLayout
=
children
[
i
].
getLayout
();
childLayout
.
x
=
sX
;
sX
+=
childLayout
.
branchwidth
;
var
_buffer0Style
=
nodeStyles
[
_buffer
[
0
].
getType
()
];
var
sY
;
if
(
_buffer
[
0
].
getType
()
===
"main"
)
sY
=
0
;
else
sY
=
_buffer0Layout
.
y
+
_buffer
[
0
].
getRenderContainer
().
getHeight
()
+
_buffer0Style
.
margin
[
2
];
for
(
var
s
=
0
;
s
<
childrenC
.
length
;
s
++
)
{
var
childLayoutC
=
childrenC
[
s
].
getLayout
();
var
childStyleC
=
nodeStyles
[
childrenC
[
s
].
getType
()
];
childLayoutC
.
y
=
sY
+
childStyleC
.
margin
[
0
];
sY
+=
childLayoutC
.
branchheight
;
}
effectSet
.
push
(
_buffer
[
0
]
);
_buffer
.
shift
();
...
...
@@ -2851,7 +2907,20 @@ KityMinder.registerModule( "LayoutBottom", function () {
var
align
=
Layout
.
align
;
var
_rectHeight
=
nodeShape
.
getHeight
();
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
)
);
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
);
};
var
updateConnectAndshIcon
=
function
(
node
)
{
...
...
@@ -2859,73 +2928,50 @@ KityMinder.registerModule( "LayoutBottom", function () {
var
Layout
=
node
.
getLayout
();
var
nodeStyle
=
nodeStyles
[
node
.
getType
()
];
var
connect
;
var
_root
=
minder
.
getRoot
();
var
_rootLayout
=
_root
.
getLayout
();
//更新连线
if
(
nodeType
===
"main"
)
{
if
(
!
Layout
.
connect
)
{
connect
=
Layout
.
connect
=
new
kity
.
Group
();
var
bezier
=
Layout
.
connect
.
bezier
=
new
kity
.
Bezier
();
var
circle
=
Layout
.
connect
.
circle
=
new
kity
.
Circle
();
connect
.
addShapes
(
[
bezier
,
circle
]
);
connect
=
Layout
.
connect
=
new
kity
.
Path
();
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
;
var
nodeShape
=
node
.
getRenderContainer
();
var
nodeClosurePoints
=
nodeShape
.
getRenderBox
().
closurePoints
;
var
sPos
;
var
endPos
;
if
(
Layout
.
appendside
===
"left"
)
{
sPos
=
new
kity
.
BezierPoint
(
rootX
-
30
,
nodeClosurePoints
[
2
].
y
+
nodeShape
.
getHeight
()
/
2
);
endPos
=
new
kity
.
BezierPoint
(
nodeClosurePoints
[
2
].
x
+
3
,
nodeClosurePoints
[
2
].
y
+
nodeShape
.
getHeight
()
/
2
);
}
else
{
sPos
=
new
kity
.
BezierPoint
(
rootX
+
30
,
nodeClosurePoints
[
3
].
y
+
nodeShape
.
getHeight
()
/
2
);
endPos
=
new
kity
.
BezierPoint
(
nodeClosurePoints
[
3
].
x
-
3
,
nodeClosurePoints
[
3
].
y
+
nodeShape
.
getHeight
()
/
2
);
}
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
);
var
sX
=
_rootLayout
.
x
;
var
sY
=
_rootLayout
.
y
+
_root
.
getRenderContainer
().
getHeight
();
var
transX
=
Layout
.
x
+
node
.
getRenderContainer
().
getWidth
()
/
2
;
var
transY
=
sY
+
nodeStyles
.
root
.
margin
[
2
];
connect
.
getDrawer
().
clear
()
.
moveTo
(
sX
,
sY
)
.
lineTo
(
sX
,
transY
)
.
lineTo
(
transX
,
transY
)
.
lineTo
(
transX
,
Layout
.
y
);
connect
.
stroke
(
nodeStyles
.
main
.
stroke
);
}
else
if
(
nodeType
===
"sub"
)
{
var
parent
=
node
.
getParent
();
var
parentLayout
=
parent
.
getLayout
();
if
(
!
Layout
.
connect
)
{
connect
=
Layout
.
connect
=
new
kity
.
Path
();
minder
.
getRenderContainer
()
.
addShape
(
connect
);
Layout
.
subgroup
.
addShape
(
connect
);
}
connect
=
Layout
.
connect
;
var
parentShape
=
node
.
getParent
().
getRenderContainer
();
var
parentBox
=
parentShape
.
getRenderBox
();
var
parentLayout
=
node
.
getParent
().
getLayout
();
var
parentStyle
=
nodeStyles
[
node
.
getParent
().
getType
()
];
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
);
var
ssX
,
ssY
;
if
(
parent
.
getType
()
===
"main"
)
{
ssX
=
10
;
ssY
=
0
;
}
else
{
sX
=
parentBox
.
closurePoints
[
0
].
x
+
parentStyle
.
margin
[
1
];
nodeX
=
Shape
.
getRenderBox
().
closurePoints
[
1
].
x
+
1
;
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
);
ssX
=
parentLayout
.
x
+
10
;
ssY
=
parentLayout
.
y
+
parent
.
getRenderContainer
().
getHeight
()
+
10
;
}
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
if
(
nodeType
!==
"root"
)
{
if
(
nodeType
!==
"root"
&&
node
.
getChildren
().
length
!==
0
)
{
if
(
!
Layout
.
shicon
)
{
Layout
.
shicon
=
new
ShIcon
(
node
);
}
...
...
@@ -2941,21 +2987,13 @@ KityMinder.registerModule( "LayoutBottom", function () {
switch
(
nodeType
)
{
case
"root"
:
case
"main"
:
case
"sub"
:
if
(
highlight
)
{
Layout
.
bgRect
.
fill
(
nodeStyle
.
highlight
);
}
else
{
Layout
.
bgRect
.
fill
(
nodeStyle
.
fill
);
}
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
:
break
;
}
...
...
@@ -2969,13 +3007,18 @@ KityMinder.registerModule( "LayoutBottom", function () {
},
false
)
);
updateShapeByCont
(
node
);
var
set1
=
updateLayoutHorizon
(
node
);
var
set2
=
updateLayoutVertical
(
node
,
node
.
getParent
(),
"change"
);
var
set
=
uSet
(
set1
,
set2
);
var
set
=
updateLayoutAll
(
node
,
node
.
getParent
(),
"change"
);
for
(
var
i
=
0
;
i
<
set
.
length
;
i
++
)
{
translateNode
(
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
()
{
var
_root
=
minder
.
getRoot
();
...
...
@@ -2991,8 +3034,7 @@ KityMinder.registerModule( "LayoutBottom", function () {
node
:
_root
},
false
)
);
updateShapeByCont
(
_root
);
updateLayoutHorizon
(
_root
);
updateLayoutVertical
(
_root
);
updateLayoutAll
(
_root
);
translateNode
(
_root
);
var
_buffer
=
[
_root
];
var
_cleanbuffer
=
[];
...
...
@@ -3013,13 +3055,22 @@ KityMinder.registerModule( "LayoutBottom", function () {
}
},
appendChildNode
:
function
(
parent
,
node
,
sibling
)
{
minder
.
handelNodeInsert
(
node
);
node
.
clearLayout
();
var
parentLayout
=
parent
.
getLayout
();
//设置分支类型
if
(
parent
.
getType
()
===
"root"
)
{
node
.
setType
(
"main"
);
minder
.
handelNodeInsert
(
node
);
}
else
{
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
);
...
...
@@ -3031,22 +3082,97 @@ KityMinder.registerModule( "LayoutBottom", function () {
node
:
node
},
false
)
);
updateShapeByCont
(
node
);
var
set2
=
updateLayoutHorizon
(
node
,
parent
,
"append"
);
var
set1
=
updateLayoutVertical
(
node
);
var
set
=
uSet
(
set1
,
set2
);
var
set
=
updateLayoutAll
(
node
,
parent
,
"append"
);
for
(
var
i
=
0
;
i
<
set
.
length
;
i
++
)
{
translateNode
(
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
)
{
var
parent
=
sibling
.
getParent
();
this
.
appendChildNode
(
parent
,
node
,
sibling
);
},
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
)
{
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
);
...
...
@@ -3344,7 +3470,7 @@ var MoveToParentCommand = kity.createClass( 'MoveToParentCommand', {
function
boxMapper
(
node
)
{
return
node
.
getRenderContainer
().
getRenderBox
();
return
node
.
getRenderContainer
().
getRenderBox
(
'top'
);
}
// 对拖动对象的一个替代盒子,控制整个拖放的逻辑,包括:
...
...
@@ -3391,6 +3517,12 @@ var DragBox = kity.createClass( "DragBox", {
ancestors
=
[],
judge
;
// 根节点不参与计算
var
rootIndex
=
nodes
.
indexOf
(
this
.
_minder
.
getRoot
()
);
if
(
~
rootIndex
)
{
nodes
.
splice
(
rootIndex
,
1
);
}
// 判断 nodes 列表中是否存在 judge 的祖先
function
hasAncestor
(
nodes
,
judge
)
{
for
(
var
i
=
nodes
.
length
-
1
;
i
>=
0
;
--
i
)
{
...
...
@@ -3449,10 +3581,15 @@ var DragBox = kity.createClass( "DragBox", {
// 4. 标记已启动
_enterDragMode
:
function
()
{
this
.
_calcDragSources
();
if
(
!
this
.
_dragSources
.
length
)
{
this
.
_startPosition
=
null
;
return
false
;
}
this
.
_calcDropTargets
();
this
.
_drawForDragMode
();
this
.
_shrink
();
this
.
_dragMode
=
true
;
return
true
;
},
_leaveDragMode
:
function
()
{
this
.
remove
();
...
...
@@ -3539,16 +3676,21 @@ var DragBox = kity.createClass( "DragBox", {
},
dragMove
:
function
(
position
)
{
// 启动拖放模式需要最小的移动距离
var
DRAG_MOVE_THRESHOLD
=
10
;
if
(
!
this
.
_startPosition
)
return
;
this
.
_dragPosition
=
position
;
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
;
}
this
.
_enterDragMode
();
}
var
movement
=
kity
.
Vector
.
fromPoints
(
this
.
_startPosition
,
this
.
_dragPosition
);
...
...
@@ -3581,7 +3723,8 @@ KityMinder.registerModule( "DragTree", function () {
},
events
:
{
mousedown
:
function
(
e
)
{
if
(
e
.
getTargetNode
()
)
{
// 单选中根节点也不触发拖拽
if
(
e
.
getTargetNode
()
&&
e
.
getTargetNode
()
!=
this
.
getRoot
()
)
{
this
.
_dragBox
.
dragStart
(
e
.
getPosition
()
);
}
},
...
...
@@ -3791,7 +3934,9 @@ KityMinder.registerModule( "Select", function () {
startPosition
=
g
.
snapToSharp
(
e
.
getPosition
()
);
},
selectMove
:
function
(
e
)
{
if
(
minder
.
isTextEditStatus
()
)
{
return
;
}
if
(
!
startPosition
)
return
;
var
p1
=
startPosition
,
...
...
@@ -3827,7 +3972,7 @@ KityMinder.registerModule( "Select", function () {
// 计算选中范围
minder
.
getRoot
().
traverse
(
function
(
node
)
{
var
renderBox
=
node
.
getRenderContainer
().
getRenderBox
();
var
renderBox
=
node
.
getRenderContainer
().
getRenderBox
(
"top"
);
if
(
g
.
isBoxIntersect
(
renderBox
,
marquee
)
)
{
selectedNodes
.
push
(
node
);
}
...
...
@@ -3842,7 +3987,7 @@ KityMinder.registerModule( "Select", function () {
}
if
(
marqueeMode
)
{
marqueeShape
.
fadeOut
(
200
,
'ease'
,
0
,
function
()
{
if
(
marqueeShape
.
remove
)
marqueeShape
.
remove
();
if
(
marqueeShape
.
remove
)
marqueeShape
.
remove
();
}
);
marqueeMode
=
false
;
}
...
...
@@ -4039,8 +4184,8 @@ KityMinder.registerModule( "HistoryModule", function () {
}
)
},
addShortcutKeys
:
{
"Undo"
:
"ctrl+
90
"
,
//undo
"Redo"
:
"ctrl+
89
"
//redo
"Undo"
:
"ctrl+
z
"
,
//undo
"Redo"
:
"ctrl+
y
"
//redo
},
"events"
:
{
"saveScene"
:
function
(
e
)
{
...
...
@@ -4095,6 +4240,12 @@ KityMinder.registerModule( "TextEditModule", function () {
km
.
isTextEditStatus
=
function
(){
return
km
.
receiver
.
isTextEditStatus
();
};
var
selectionByClick
=
false
;
return
{
//插入光标
"init"
:
function
(){
...
...
@@ -4104,12 +4255,19 @@ KityMinder.registerModule( "TextEditModule", function () {
'beforemousedown'
:
function
(
e
){
sel
.
setHide
();
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
){
var
textShape
=
node
.
getTextShape
();
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
();
node
.
getTextShape
().
setStyle
(
'cursor'
,
'text'
);
receiver
.
setTextEditStatus
(
true
)
...
...
@@ -4123,27 +4281,44 @@ KityMinder.registerModule( "TextEditModule", function () {
.
setCurrentIndex
(
e
.
getPosition
())
.
updateSelection
()
.
setRange
(
range
);
sel
.
setData
(
'relatedNode'
,
node
);
mouseDownStatus
=
true
;
lastEvtPosition
=
e
.
getPosition
();
if
(
selectionByClick
){
sel
.
setShow
();
selectionByClick
=
false
;
}
}
}
},
'mouseup'
:
function
(
e
){
if
(
!
sel
.
collapsed
&&
mouseDownStatus
){
if
(
mouseDownStatus
){
if
(
!
sel
.
collapsed
){
receiver
.
updateRange
(
range
)
}
else
sel
.
setShow
()
}
mouseDownStatus
=
false
;
oneTime
=
0
;
},
'beforemousemove'
:
function
(
e
){
if
(
mouseDownStatus
){
e
.
stopPropagationImmediately
();
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
);
receiver
.
updateSelectionByMousePosition
(
offset
,
dir
)
.
updateSelectionShow
(
dir
);
sel
.
stroke
(
'none'
,
0
);
lastEvtPosition
=
e
.
getPosition
();
}
},
'dblclick'
:
function
(
e
){
...
...
@@ -4154,8 +4329,8 @@ KityMinder.registerModule( "TextEditModule", function () {
sel
.
setStartOffset
(
0
);
sel
.
setEndOffset
(
text
.
getContent
().
length
);
sel
.
setShow
();
receiver
.
updateSelectionShow
(
1
)
.
updateRange
(
range
)
;
receiver
.
setContainerTxt
(
text
.
getContent
()).
updateSelectionShow
(
1
)
.
updateRange
(
range
)
.
setTextEditStatus
(
true
)
}
},
...
...
@@ -4198,7 +4373,7 @@ KityMinder.registerModule( "TextEditModule", function () {
receiver
.
updateSelectionShow
(
1
)
.
updateRange
(
range
);
return
;
}
...
...
@@ -4211,10 +4386,11 @@ KityMinder.registerModule( "TextEditModule", function () {
}
else
{
receiver
.
updateSelectionShow
(
1
)
}
return
;
}
receiver
.
clear
().
setTextEditStatus
(
false
);
},
'selectionclear'
:
function
(){
receiver
.
setTextEditStatus
(
false
).
clear
()
...
...
@@ -4241,7 +4417,12 @@ Minder.Range = kity.createClass('Range',{
return
this
;
},
setStart
:
function
(
node
,
index
){
try
{
this
.
nativeRange
.
setStart
(
node
,
index
);
}
catch
(
e
){
console
.
log
(
e
)
}
return
this
;
},
setEnd
:
function
(
node
,
index
){
...
...
@@ -4490,16 +4671,17 @@ Minder.Receiver = kity.createClass('Receiver',{
return
false
;
}
if
(
offset
.
x
>=
v
.
x
&&
offset
.
x
<=
v
.
x
+
v
.
width
){
if
(
me
.
index
==
i
){
if
(
i
==
0
){
me
.
selection
.
setStartOffset
(
i
)
}
me
.
selection
.
setEndOffset
(
i
+
(
dir
==
1
?
1
:
0
))
}
else
if
(
i
>
me
.
index
){
me
.
selection
.
setStartOffset
(
me
.
index
);
me
.
selection
.
setEndOffset
(
i
+
(
dir
==
1
?
1
:
0
))
}
else
{
me
.
selection
.
setStartOffset
(
i
+
(
dir
==
1
?
1
:
0
))
me
.
selection
.
setStartOffset
(
i
+
(
dir
==
1
?
1
:
0
));
me
.
selection
.
setEndOffset
(
me
.
index
)
}
return
false
;
...
...
@@ -4513,7 +4695,7 @@ Minder.Receiver = kity.createClass('Receiver',{
width
=
0
;
if
(
this
.
selection
.
collapsed
){
this
.
selection
.
updateShow
(
startOffset
,
0
);
this
.
selection
.
updateShow
(
startOffset
||
this
.
textData
[
this
.
textData
.
length
-
1
]
,
0
);
return
this
;
}
if
(
!
endOffset
){
...
...
@@ -4536,6 +4718,10 @@ Minder.Receiver = kity.createClass('Receiver',{
setIndex
:
function
(
index
){
this
.
index
=
index
;
return
this
},
setContainerTxt
:
function
(
txt
){
this
.
container
.
textContent
=
txt
;
return
this
;
}
});
...
...
@@ -4546,18 +4732,20 @@ Minder.Selection = kity.createClass( 'Selection', {
this
.
callBase
();
this
.
height
=
height
||
20
;
this
.
stroke
(
color
||
'
blue
'
,
width
||
1
);
this
.
width
=
1
;
this
.
fill
(
'
#99C8FF
'
);
this
.
stroke
(
color
||
'
rgb(27,171,255)
'
,
width
||
1
);
this
.
width
=
0
;
this
.
fill
(
'
rgb(27,171,255)
'
);
this
.
setHide
();
this
.
timer
=
null
;
this
.
collapsed
=
true
;
this
.
startOffset
=
this
.
endOffset
=
0
;
this
.
setOpacity
(
0.5
)
this
.
setOpacity
(
0.5
);
this
.
setStyle
(
'cursor'
,
'text'
);
},
collapse
:
function
(
toEnd
){
this
.
stroke
(
'blue'
,
1
);
this
.
stroke
(
'rgb(27,171,255)'
,
1
);
this
.
setOpacity
(
1
);
this
.
width
=
1
;
this
.
collapsed
=
true
;
if
(
toEnd
){
...
...
@@ -4578,7 +4766,8 @@ Minder.Selection = kity.createClass( 'Selection', {
return
this
;
}
this
.
collapsed
=
false
;
this
.
stroke
(
'none'
);
this
.
stroke
(
'none'
,
0
);
this
.
setOpacity
(
0.5
);
return
this
;
},
setEndOffset
:
function
(
offset
){
...
...
@@ -4592,10 +4781,14 @@ Minder.Selection = kity.createClass( 'Selection', {
return
this
;
}
this
.
collapsed
=
false
;
this
.
stroke
(
'none'
);
this
.
stroke
(
'none'
,
0
);
this
.
setOpacity
(
0.5
);
return
this
;
},
updateShow
:
function
(
offset
,
width
){
if
(
width
){
this
.
setShowHold
();
}
this
.
setPosition
(
offset
).
setWidth
(
width
);
return
this
;
},
...
...
@@ -4605,7 +4798,7 @@ Minder.Selection = kity.createClass( 'Selection', {
this
.
y
=
offset
.
y
;
}
catch
(
e
)
{
console
.
log
(
e
)
debugger
}
return
this
.
update
();
...
...
@@ -4728,8 +4921,8 @@ KityMinder.registerModule( "basestylemodule", function () {
}
)
},
addShortcutKeys
:
{
"bold"
:
"ctrl+
66
"
,
//bold
"italic"
:
"ctrl+
73
"
//italic
"bold"
:
"ctrl+
b
"
,
//bold
"italic"
:
"ctrl+
i
"
//italic
},
"events"
:
{
"beforeRenderNode"
:
function
(
e
)
{
...
...
@@ -4909,7 +5102,7 @@ KityMinder.registerModule( 'Zoom', function () {
'zoom-out'
:
ZoomOutCommand
},
addShortcutKeys
:
{
"zoom-in"
:
"
+
"
,
//=
"zoom-in"
:
"
=
"
,
//=
"zoom-out"
:
"-"
//-
},
events
:
{
...
...
@@ -5755,7 +5948,7 @@ KM.ui.define('colorpicker', {
"<%if(autoRecord) {%>"
+
"<%for( var i=0, len = recordStack.length; i<len; 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>"
+
"<label class=
\"
<%=labelClassName%>
\"
style=
\"
<%=itemStyles[ index ]%>
\"
unselectable=
\"
on
\"
onmousedown=
\"
return false
\"
><%=items[index]%></label>"
+
"</li>"
+
...
...
@@ -5765,7 +5958,7 @@ KM.ui.define('colorpicker', {
"<%}%>"
+
"<%}%>"
+
"<%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>"
+
"<label class=
\"
<%=labelClassName%>
\"
style=
\"
<%=itemStyles[ i ]%>
\"
unselectable=
\"
on
\"
onmousedown=
\"
return false
\"
><%=label%></label>"
+
"</li>"
+
...
...
@@ -5780,10 +5973,13 @@ KM.ui.define('colorpicker', {
value
:
[],
comboboxName
:
''
,
selected
:
''
,
//初始禁用状态
disabled
:
{},
//自动记录
autoRecord
:
true
,
//最多记录条数
recordCount
:
5
recordCount
:
5
,
enabledRecord
:
true
},
init
:
function
(
options
){
...
...
@@ -5821,6 +6017,7 @@ KM.ui.define('colorpicker', {
initSelectItem
:
function
(){
var
me
=
this
,
options
=
me
.
data
(
"options"
),
labelClass
=
"."
+
labelClassName
;
me
.
root
().
delegate
(
'.'
+
itemClassName
,
'click'
,
function
(){
...
...
@@ -5828,6 +6025,10 @@ KM.ui.define('colorpicker', {
var
$li
=
$
(
this
),
index
=
$li
.
attr
(
'data-item-index'
);
if
(
options
.
disabled
[
index
]
)
{
return
false
;
}
me
.
trigger
(
'comboboxselect'
,
{
index
:
index
,
label
:
$li
.
find
(
labelClass
).
text
(),
...
...
@@ -5860,11 +6061,18 @@ KM.ui.define('colorpicker', {
*/
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
)
{
items
=
this
.
data
(
'options'
).
items
;
items
=
options
.
items
;
}
// 禁用
if
(
options
.
disabled
[
index
]
)
{
return
null
;
}
if
(
itemCount
==
0
)
{
...
...
@@ -5883,6 +6091,7 @@ KM.ui.define('colorpicker', {
this
.
trigger
(
'changebefore'
,
items
[
index
]
);
this
.
_update
(
index
);
this
.
trigger
(
'changeafter'
,
items
[
index
]
);
...
...
@@ -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', {
_update
:
function
(
index
)
{
var
options
=
this
.
data
(
"options"
),
newStack
=
[],
newChilds
=
null
;
newStack
=
[];
if
(
this
.
data
(
'options'
).
enabledRecord
){
$
.
each
(
options
.
recordStack
,
function
(
i
,
item
){
if
(
item
!=
index
)
{
...
...
@@ -6009,15 +6277,24 @@ KM.ui.define('colorpicker', {
}
options
.
recordStack
=
newStack
;
}
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
()
);
newChilds
=
null
;
newStack
=
null
;
}
};
...
...
@@ -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
,
label
=
me
.
getLang
(
'tooltips.'
+
name
),
...
...
@@ -6769,9 +7046,7 @@ KM.registerToolbarUI( 'layoutstyle fontfamily fontsize', function ( name ) {
}
switch
(
name
)
{
case
'layoutstyle'
:
options
=
transForLayoutstyle
(
options
);
break
;
case
'fontfamily'
:
options
=
transForFontfamily
(
options
);
...
...
@@ -6812,24 +7087,6 @@ KM.registerToolbarUI( 'layoutstyle fontfamily fontsize', function ( name ) {
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
)
{
...
...
@@ -6954,7 +7211,8 @@ KM.registerToolbarUI( 'saveto', function ( name ) {
items
:
[],
itemStyles
:
[],
value
:
[],
autowidthitem
:
[]
autowidthitem
:
[],
enabledRecord
:
false
},
$combox
=
null
,
comboboxWidget
=
null
;
...
...
@@ -6975,6 +7233,53 @@ KM.registerToolbarUI( 'saveto', function ( name ) {
comboboxWidget
=
$combox
.
kmui
();
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
p
=
KityMinder
.
findProtocal
(
res
.
value
);
var
a
=
downloadLink
;
...
...
@@ -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
()
{
var
LINE_ENDING
=
'
\
n'
,
TAB_CHAR
=
'
\
t'
;
...
...
@@ -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
};
}
);
dist/dev.php
View file @
6b25e103
...
...
@@ -62,8 +62,11 @@ $dependency = Array(
,
'src/adapter/view.js'
,
'src/adapter/dialog.js'
,
'src/adapter/tooltips.js'
,
'src/adapter/layout.js'
,
'src/adapter/node.js'
,
'src/protocal/plain.js'
,
'src/protocal/json.js'
,
'src/protocal/png.js'
);
$content
=
""
;
...
...
kity
@
7c049801
Subproject commit
a9630e638b29633f62cdc2df239bc702118b231a
Subproject commit
7c0498012df602619a38e6b88785a486cd92396d
kityminder计划.oplx/Actual.xml
deleted
100644 → 0
View file @
71e6130a
<?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>
kityminder计划.oplx/__TOC.xml
deleted
100644 → 0
View file @
71e6130a
<?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>
kityminder计划.oplx/__changelog.xml
deleted
100644 → 0
View file @
71e6130a
<?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=
"{
"font-fill" = {
b = 1;
g = "0.436444";
r = "0.299775";
};
}"
/>
<change
idref=
"t1"
attribute=
"internalEffortDone"
type=
"real"
from=
"0"
to=
"28800"
/>
<change
idref=
"t2"
attribute=
"styleDict"
type=
"dict"
to=
"{
"font-fill" = {
b = 1;
g = "0.436444";
r = "0.299775";
};
}"
/>
<change
idref=
"t2"
attribute=
"internalEffortDone"
type=
"real"
from=
"0"
to=
"57600"
/>
<change
idref=
"t3"
attribute=
"styleDict"
type=
"dict"
to=
"{
"font-fill" = {
b = 1;
g = "0.436444";
r = "0.299775";
};
}"
/>
<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>
lang/zh-cn/zh-cn.js
View file @
6b25e103
...
...
@@ -10,11 +10,13 @@ KityMinder.LANG[ 'zh-cn' ] = {
'fontfamily'
:
'字体'
,
'fontsize'
:
'字号'
,
'layoutstyle'
:
'主题'
,
'node'
:
'节点操作'
,
'saveto'
:
'导出'
,
'hand'
:
'允许拖拽'
,
'zoom-in'
:
'放大'
,
'zoom-out'
:
'缩小'
,
'markers'
:
'添加标签'
'markers'
:
'添加标签'
,
'switchlayout'
:
'切换主题'
},
'popupcolor'
:
{
'clearColor'
:
'清空颜色'
,
...
...
@@ -35,9 +37,14 @@ KityMinder.LANG[ 'zh-cn' ] = {
'quarterdone'
:
'完成1/4'
,
'halfdone'
:
'完成1/2'
,
'threequartersdone'
:
'完成3/4'
,
'done'
:
'已完成'
,
'done'
:
'已完成'
}
}
},
'node'
:
{
'appendsiblingnode'
:
'插入兄弟节点'
,
'appendchildnode'
:
'插入孩子节点'
,
'removenode'
:
'删除节点'
}
};
\ No newline at end of file
spec/交互点说明.md
0 → 100644
View file @
6b25e103
测试要点
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 下载的文件拖动到画布上,可以还原原来的数据
src/adapter/combobox.js
View file @
6b25e103
KM
.
registerToolbarUI
(
'
layoutstyle
fontfamily fontsize'
,
function
(
name
)
{
KM
.
registerToolbarUI
(
'fontfamily fontsize'
,
function
(
name
)
{
var
me
=
this
,
label
=
me
.
getLang
(
'tooltips.'
+
name
),
...
...
@@ -19,9 +19,7 @@ KM.registerToolbarUI( 'layoutstyle fontfamily fontsize', function ( name ) {
}
switch
(
name
)
{
case
'layoutstyle'
:
options
=
transForLayoutstyle
(
options
);
break
;
case
'fontfamily'
:
options
=
transForFontfamily
(
options
);
...
...
@@ -62,24 +60,6 @@ KM.registerToolbarUI( 'layoutstyle fontfamily fontsize', function ( name ) {
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
)
{
...
...
src/adapter/layout.js
0 → 100644
View file @
6b25e103
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
src/adapter/node.js
0 → 100644
View file @
6b25e103
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
src/adapter/saveto.js
View file @
6b25e103
...
...
@@ -9,7 +9,8 @@ KM.registerToolbarUI( 'saveto', function ( name ) {
items
:
[],
itemStyles
:
[],
value
:
[],
autowidthitem
:
[]
autowidthitem
:
[],
enabledRecord
:
false
},
$combox
=
null
,
comboboxWidget
=
null
;
...
...
@@ -30,6 +31,53 @@ KM.registerToolbarUI( 'saveto', function ( name ) {
comboboxWidget
=
$combox
.
kmui
();
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
p
=
KityMinder
.
findProtocal
(
res
.
value
);
var
a
=
downloadLink
;
...
...
src/core/keymap.js
View file @
6b25e103
...
...
@@ -28,5 +28,14 @@ var keymap = KityMinder.keymap = {
'NumLock'
:
144
,
'Cmd'
:
91
'Cmd'
:
91
,
'='
:
187
,
'-'
:
189
,
"b"
:
66
,
'i'
:
73
,
'z'
:
90
,
'y'
:
89
};
\ No newline at end of file
src/core/minder.js
View file @
6b25e103
...
...
@@ -69,6 +69,9 @@ var Minder = KityMinder.Minder = kity.createClass( "KityMinder", {
this
.
_shortcutkeys
=
{};
this
.
_bindshortcutKeys
();
},
isTextEditStatus
:
function
(){
return
false
;
},
addShortcutKeys
:
function
(
cmd
,
keys
)
{
var
obj
=
{},
km
=
this
;
if
(
keys
)
{
...
...
@@ -87,25 +90,50 @@ var Minder = KityMinder.Minder = kity.createClass( "KityMinder", {
_bindshortcutKeys
:
function
()
{
var
me
=
this
,
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
keyCode
=
originEvent
.
keyCode
||
originEvent
.
which
;
for
(
var
i
in
shortcutkeys
)
{
var
tmp
=
shortcutkeys
[
i
].
split
(
','
);
for
(
var
t
=
0
,
ti
;
ti
=
tmp
[
t
++
];
)
{
ti
=
ti
.
split
(
':'
);
var
key
=
ti
[
0
],
param
=
ti
[
1
];
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
();
var
keys
=
shortcutkeys
[
i
].
toLowerCase
().
split
(
'+'
);
var
current
=
0
;
utils
.
each
(
keys
,
function
(
i
,
k
){
if
(
checkkey
(
k
,
keyCode
,
originEvent
)){
current
++
;
}
});
//todo 暂时通过receiver判断
if
(
me
.
isTextEditStatus
()){
return
;
}
if
(
current
==
keys
.
length
){
if
(
me
.
queryCommandState
(
i
)
!=
-
1
)
me
.
execCommand
(
i
);
originEvent
.
preventDefault
();
break
;
}
}
...
...
src/module/basestyle.js
View file @
6b25e103
...
...
@@ -69,8 +69,8 @@ KityMinder.registerModule( "basestylemodule", function () {
}
)
},
addShortcutKeys
:
{
"bold"
:
"ctrl+
66
"
,
//bold
"italic"
:
"ctrl+
73
"
//italic
"bold"
:
"ctrl+
b
"
,
//bold
"italic"
:
"ctrl+
i
"
//italic
},
"events"
:
{
"beforeRenderNode"
:
function
(
e
)
{
...
...
src/module/dragtree.js
View file @
6b25e103
...
...
@@ -32,7 +32,7 @@ var MoveToParentCommand = kity.createClass( 'MoveToParentCommand', {
function
boxMapper
(
node
)
{
return
node
.
getRenderContainer
().
getRenderBox
();
return
node
.
getRenderContainer
().
getRenderBox
(
'top'
);
}
// 对拖动对象的一个替代盒子,控制整个拖放的逻辑,包括:
...
...
@@ -79,6 +79,12 @@ var DragBox = kity.createClass( "DragBox", {
ancestors
=
[],
judge
;
// 根节点不参与计算
var
rootIndex
=
nodes
.
indexOf
(
this
.
_minder
.
getRoot
()
);
if
(
~
rootIndex
)
{
nodes
.
splice
(
rootIndex
,
1
);
}
// 判断 nodes 列表中是否存在 judge 的祖先
function
hasAncestor
(
nodes
,
judge
)
{
for
(
var
i
=
nodes
.
length
-
1
;
i
>=
0
;
--
i
)
{
...
...
@@ -137,10 +143,15 @@ var DragBox = kity.createClass( "DragBox", {
// 4. 标记已启动
_enterDragMode
:
function
()
{
this
.
_calcDragSources
();
if
(
!
this
.
_dragSources
.
length
)
{
this
.
_startPosition
=
null
;
return
false
;
}
this
.
_calcDropTargets
();
this
.
_drawForDragMode
();
this
.
_shrink
();
this
.
_dragMode
=
true
;
return
true
;
},
_leaveDragMode
:
function
()
{
this
.
remove
();
...
...
@@ -227,16 +238,21 @@ var DragBox = kity.createClass( "DragBox", {
},
dragMove
:
function
(
position
)
{
// 启动拖放模式需要最小的移动距离
var
DRAG_MOVE_THRESHOLD
=
10
;
if
(
!
this
.
_startPosition
)
return
;
this
.
_dragPosition
=
position
;
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
;
}
this
.
_enterDragMode
();
}
var
movement
=
kity
.
Vector
.
fromPoints
(
this
.
_startPosition
,
this
.
_dragPosition
);
...
...
@@ -269,7 +285,8 @@ KityMinder.registerModule( "DragTree", function () {
},
events
:
{
mousedown
:
function
(
e
)
{
if
(
e
.
getTargetNode
()
)
{
// 单选中根节点也不触发拖拽
if
(
e
.
getTargetNode
()
&&
e
.
getTargetNode
()
!=
this
.
getRoot
()
)
{
this
.
_dragBox
.
dragStart
(
e
.
getPosition
()
);
}
},
...
...
src/module/editor.js
View file @
6b25e103
...
...
@@ -14,6 +14,12 @@ KityMinder.registerModule( "TextEditModule", function () {
km
.
isTextEditStatus
=
function
(){
return
km
.
receiver
.
isTextEditStatus
();
};
var
selectionByClick
=
false
;
return
{
//插入光标
"init"
:
function
(){
...
...
@@ -23,12 +29,19 @@ KityMinder.registerModule( "TextEditModule", function () {
'beforemousedown'
:
function
(
e
){
sel
.
setHide
();
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
){
var
textShape
=
node
.
getTextShape
();
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
();
node
.
getTextShape
().
setStyle
(
'cursor'
,
'text'
);
receiver
.
setTextEditStatus
(
true
)
...
...
@@ -42,27 +55,44 @@ KityMinder.registerModule( "TextEditModule", function () {
.
setCurrentIndex
(
e
.
getPosition
())
.
updateSelection
()
.
setRange
(
range
);
sel
.
setData
(
'relatedNode'
,
node
);
mouseDownStatus
=
true
;
lastEvtPosition
=
e
.
getPosition
();
if
(
selectionByClick
){
sel
.
setShow
();
selectionByClick
=
false
;
}
}
}
},
'mouseup'
:
function
(
e
){
if
(
!
sel
.
collapsed
&&
mouseDownStatus
){
if
(
mouseDownStatus
){
if
(
!
sel
.
collapsed
){
receiver
.
updateRange
(
range
)
}
else
sel
.
setShow
()
}
mouseDownStatus
=
false
;
oneTime
=
0
;
},
'beforemousemove'
:
function
(
e
){
if
(
mouseDownStatus
){
e
.
stopPropagationImmediately
();
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
);
receiver
.
updateSelectionByMousePosition
(
offset
,
dir
)
.
updateSelectionShow
(
dir
);
sel
.
stroke
(
'none'
,
0
);
lastEvtPosition
=
e
.
getPosition
();
}
},
'dblclick'
:
function
(
e
){
...
...
@@ -73,8 +103,8 @@ KityMinder.registerModule( "TextEditModule", function () {
sel
.
setStartOffset
(
0
);
sel
.
setEndOffset
(
text
.
getContent
().
length
);
sel
.
setShow
();
receiver
.
updateSelectionShow
(
1
)
.
updateRange
(
range
)
;
receiver
.
setContainerTxt
(
text
.
getContent
()).
updateSelectionShow
(
1
)
.
updateRange
(
range
)
.
setTextEditStatus
(
true
)
}
},
...
...
@@ -117,7 +147,7 @@ KityMinder.registerModule( "TextEditModule", function () {
receiver
.
updateSelectionShow
(
1
)
.
updateRange
(
range
);
return
;
}
...
...
@@ -130,10 +160,11 @@ KityMinder.registerModule( "TextEditModule", function () {
}
else
{
receiver
.
updateSelectionShow
(
1
)
}
return
;
}
receiver
.
clear
().
setTextEditStatus
(
false
);
},
'selectionclear'
:
function
(){
receiver
.
setTextEditStatus
(
false
).
clear
()
...
...
src/module/editor.range.js
View file @
6b25e103
...
...
@@ -16,7 +16,12 @@ Minder.Range = kity.createClass('Range',{
return
this
;
},
setStart
:
function
(
node
,
index
){
try
{
this
.
nativeRange
.
setStart
(
node
,
index
);
}
catch
(
e
){
console
.
log
(
e
)
}
return
this
;
},
setEnd
:
function
(
node
,
index
){
...
...
src/module/editor.receiver.js
View file @
6b25e103
...
...
@@ -223,16 +223,17 @@ Minder.Receiver = kity.createClass('Receiver',{
return
false
;
}
if
(
offset
.
x
>=
v
.
x
&&
offset
.
x
<=
v
.
x
+
v
.
width
){
if
(
me
.
index
==
i
){
if
(
i
==
0
){
me
.
selection
.
setStartOffset
(
i
)
}
me
.
selection
.
setEndOffset
(
i
+
(
dir
==
1
?
1
:
0
))
}
else
if
(
i
>
me
.
index
){
me
.
selection
.
setStartOffset
(
me
.
index
);
me
.
selection
.
setEndOffset
(
i
+
(
dir
==
1
?
1
:
0
))
}
else
{
me
.
selection
.
setStartOffset
(
i
+
(
dir
==
1
?
1
:
0
))
me
.
selection
.
setStartOffset
(
i
+
(
dir
==
1
?
1
:
0
));
me
.
selection
.
setEndOffset
(
me
.
index
)
}
return
false
;
...
...
@@ -246,7 +247,7 @@ Minder.Receiver = kity.createClass('Receiver',{
width
=
0
;
if
(
this
.
selection
.
collapsed
){
this
.
selection
.
updateShow
(
startOffset
,
0
);
this
.
selection
.
updateShow
(
startOffset
||
this
.
textData
[
this
.
textData
.
length
-
1
]
,
0
);
return
this
;
}
if
(
!
endOffset
){
...
...
@@ -269,5 +270,9 @@ Minder.Receiver = kity.createClass('Receiver',{
setIndex
:
function
(
index
){
this
.
index
=
index
;
return
this
},
setContainerTxt
:
function
(
txt
){
this
.
container
.
textContent
=
txt
;
return
this
;
}
});
\ No newline at end of file
src/module/editor.selection.js
View file @
6b25e103
...
...
@@ -5,18 +5,20 @@ Minder.Selection = kity.createClass( 'Selection', {
this
.
callBase
();
this
.
height
=
height
||
20
;
this
.
stroke
(
color
||
'
blue
'
,
width
||
1
);
this
.
width
=
1
;
this
.
fill
(
'
#99C8FF
'
);
this
.
stroke
(
color
||
'
rgb(27,171,255)
'
,
width
||
1
);
this
.
width
=
0
;
this
.
fill
(
'
rgb(27,171,255)
'
);
this
.
setHide
();
this
.
timer
=
null
;
this
.
collapsed
=
true
;
this
.
startOffset
=
this
.
endOffset
=
0
;
this
.
setOpacity
(
0.5
)
this
.
setOpacity
(
0.5
);
this
.
setStyle
(
'cursor'
,
'text'
);
},
collapse
:
function
(
toEnd
){
this
.
stroke
(
'blue'
,
1
);
this
.
stroke
(
'rgb(27,171,255)'
,
1
);
this
.
setOpacity
(
1
);
this
.
width
=
1
;
this
.
collapsed
=
true
;
if
(
toEnd
){
...
...
@@ -37,7 +39,8 @@ Minder.Selection = kity.createClass( 'Selection', {
return
this
;
}
this
.
collapsed
=
false
;
this
.
stroke
(
'none'
);
this
.
stroke
(
'none'
,
0
);
this
.
setOpacity
(
0.5
);
return
this
;
},
setEndOffset
:
function
(
offset
){
...
...
@@ -51,10 +54,14 @@ Minder.Selection = kity.createClass( 'Selection', {
return
this
;
}
this
.
collapsed
=
false
;
this
.
stroke
(
'none'
);
this
.
stroke
(
'none'
,
0
);
this
.
setOpacity
(
0.5
);
return
this
;
},
updateShow
:
function
(
offset
,
width
){
if
(
width
){
this
.
setShowHold
();
}
this
.
setPosition
(
offset
).
setWidth
(
width
);
return
this
;
},
...
...
@@ -64,7 +71,7 @@ Minder.Selection = kity.createClass( 'Selection', {
this
.
y
=
offset
.
y
;
}
catch
(
e
)
{
console
.
log
(
e
)
debugger
}
return
this
.
update
();
...
...
src/module/history.js
View file @
6b25e103
...
...
@@ -138,8 +138,8 @@ KityMinder.registerModule( "HistoryModule", function () {
}
)
},
addShortcutKeys
:
{
"Undo"
:
"ctrl+
90
"
,
//undo
"Redo"
:
"ctrl+
89
"
//redo
"Undo"
:
"ctrl+
z
"
,
//undo
"Redo"
:
"ctrl+
y
"
//redo
},
"events"
:
{
"saveScene"
:
function
(
e
)
{
...
...
src/module/layout.bottom.js
View file @
6b25e103
...
...
@@ -17,21 +17,24 @@ KityMinder.registerModule( "LayoutBottom", function () {
var
iconShape
=
this
.
shape
=
new
kity
.
Group
();
iconShape
.
class
=
"shicon"
;
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
();
plus
.
getDrawer
()
.
moveTo
(
-
3
,
0
)
.
lineTo
(
3
,
0
)
.
moveTo
(
0
,
-
3
)
.
lineTo
(
0
,
3
);
.
moveTo
(
2
,
5
)
.
lineTo
(
8
,
5
)
.
moveTo
(
5
,
2
)
.
lineTo
(
5
,
8
);
plus
.
stroke
(
"gray"
);
var
dec
=
this
.
_dec
=
new
kity
.
Path
();
dec
.
getDrawer
()
.
moveTo
(
-
3
,
0
)
.
lineTo
(
3
,
0
);
.
moveTo
(
2
,
5
)
.
lineTo
(
8
,
5
);
dec
.
stroke
(
"gray"
);
minder
.
getRenderContainer
().
addShape
(
iconShape
);
iconShape
.
addShapes
(
[
circle
,
plus
,
dec
]
);
if
(
node
.
getType
()
===
"main"
)
minder
.
getRenderContainer
().
addShape
(
iconShape
);
else
{
node
.
getLayout
().
subgroup
.
addShape
(
iconShape
);
}
iconShape
.
addShapes
(
[
rect
,
plus
,
dec
]
);
this
.
update
();
this
.
switchState
();
},
...
...
@@ -51,12 +54,9 @@ KityMinder.registerModule( "LayoutBottom", function () {
var
node
=
this
.
_node
;
var
Layout
=
node
.
getLayout
();
var
nodeShape
=
node
.
getRenderContainer
();
var
nodeX
,
nodeY
=
(
node
.
getType
()
===
"main"
?
Layout
.
y
:
(
Layout
.
y
+
nodeShape
.
getHeight
()
/
2
-
5
)
);
if
(
Layout
.
appendside
===
"left"
)
{
nodeX
=
nodeShape
.
getRenderBox
().
closurePoints
[
1
].
x
-
6
;
}
else
{
nodeX
=
nodeShape
.
getRenderBox
().
closurePoints
[
0
].
x
+
6
;
}
var
nodeType
=
node
.
getType
();
var
nodeX
=
nodeShape
.
getRenderBox
().
closurePoints
[
1
].
x
+
5
;
var
nodeY
=
nodeShape
.
getRenderBox
().
closurePoints
[
0
].
y
;
this
.
shape
.
setTransform
(
new
kity
.
Matrix
().
translate
(
nodeX
,
nodeY
)
);
},
remove
:
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
=
{
"root"
:
{
...
...
@@ -81,8 +71,8 @@ KityMinder.registerModule( "LayoutBottom", function () {
fill
:
'#e9df98'
,
fontSize
:
24
,
padding
:
[
15.5
,
25.5
,
15.5
,
25.5
],
margin
:
[
0
,
0
,
0
,
0
],
radius
:
3
0
,
margin
:
[
0
,
0
,
2
0
,
0
],
radius
:
0
,
highlight
:
'rgb(254, 219, 0)'
},
"main"
:
{
...
...
@@ -91,17 +81,18 @@ KityMinder.registerModule( "LayoutBottom", function () {
color
:
"#333"
,
padding
:
[
6.5
,
20
,
6.5
,
20
],
fontSize
:
16
,
margin
:
[
0
,
10
,
30
,
5
0
],
radius
:
1
0
,
margin
:
[
20
,
20
,
10
,
1
0
],
radius
:
0
,
highlight
:
'rgb(254, 219, 0)'
},
"sub"
:
{
stroke
:
new
kity
.
Pen
(
"white"
,
2
).
setLineCap
(
"round"
).
setLineJoin
(
"round"
),
color
:
"
white
"
,
color
:
"
#333
"
,
fontSize
:
12
,
margin
:
[
0
,
10
,
20
,
6
],
margin
:
[
10
,
10
,
10
,
30
],
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 () {
Layout
.
bgShadow
.
fill
(
'black'
).
setOpacity
(
0.2
).
setRadius
(
nodeStyle
.
radius
).
translate
(
3
,
5
);
break
;
case
"sub"
:
var
underline
=
Layout
.
underline
=
new
kity
.
Path
();
var
highlightshape
=
Layout
.
highlightshape
=
new
kity
.
Rect
().
setRadius
(
4
);
node
.
getBgRc
().
clear
().
addShapes
(
[
Layout
.
bgRect
=
new
kity
.
Rect
().
setRadius
(
4
),
highlightshape
,
underline
]
);
var
bgRc
=
node
.
getBgRc
().
clear
();
bgRc
.
addShape
(
Layout
.
bgRect
=
new
kity
.
Rect
()
);
Layout
.
bgRect
.
fill
(
nodeStyle
.
fill
);
break
;
default
:
break
;
...
...
@@ -134,6 +125,10 @@ KityMinder.registerModule( "LayoutBottom", function () {
var
nodeStyle
=
nodeStyles
[
nodeType
];
var
txtShape
=
node
.
getTextShape
();
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
)
{
...
...
@@ -152,18 +147,8 @@ KityMinder.registerModule( "LayoutBottom", function () {
Layout
.
bgShadow
.
setWidth
(
width
).
setHeight
(
height
);
break
;
case
"sub"
:
var
_contWidth
=
contRc
.
getWidth
();
var
_contHeight
=
contRc
.
getHeight
();
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
]
);
width
=
_contRCWidth
+
nodeStyle
.
padding
[
1
]
+
nodeStyle
.
padding
[
3
];
height
=
_contRCHeight
+
nodeStyle
.
padding
[
0
]
+
nodeStyle
.
padding
[
2
];
Layout
.
bgRect
.
setWidth
(
width
).
setHeight
(
height
);
break
;
default
:
...
...
@@ -171,87 +156,95 @@ KityMinder.registerModule( "LayoutBottom", function () {
}
contRc
.
setTransform
(
new
kity
.
Matrix
().
translate
(
nodeStyle
.
padding
[
3
],
nodeStyle
.
padding
[
0
]
+
node
.
getTextShape
().
getHeight
()
)
);
};
//计算节点在垂直方向的位置
var
updateLayoutVertical
=
function
(
node
)
{
var
updateLayoutMain
=
function
()
{
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
parent
=
node
.
getParent
();
var
effectSet
=
[
node
];
var
Layout
=
node
.
getLayout
();
var
_buffer
=
[
node
];
while
(
_buffer
.
length
!==
0
)
{
var
prt
=
_buffer
[
0
].
getParent
();
_buffer
=
_buffer
.
concat
(
_buffer
[
0
].
getChildren
()
);
if
(
!
prt
)
{
var
_root
=
minder
.
getRoot
();
var
rootLayout
=
_root
.
getLayout
();
if
(
nodeType
===
"root"
)
{
Layout
.
x
=
getMinderSize
().
width
/
2
;
Layout
.
y
=
100
;
_buffer
.
shift
();
continue
;
}
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
;
Layout
.
align
=
"center"
;
effectSet
.
push
(
node
);
var
children
=
node
.
getChildren
();
for
(
var
i
=
0
;
i
<
children
.
length
;
i
++
)
{
var
childLayout
=
children
[
i
].
getLayout
();
if
(
children
[
i
].
getRenderContainer
().
getWidth
()
!==
0
)
sum
+=
childLayout
.
branchwidth
;
childLayout
.
y
=
Layout
.
y
+
node
.
getRenderContainer
().
getHeight
()
+
nodeStyles
.
root
.
margin
[
2
]
+
nodeStyles
.
main
.
margin
[
0
];
}
return
sum
;
}
)();
return
(
selfWidth
>
childWidth
?
selfWidth
:
childWidth
);
};
if
(
nodeType
===
"root"
)
{
Layout
.
x
=
getMinderSize
().
width
/
2
-
node
.
getRenderContainer
().
getWidth
()
/
2
;
effectSet
.
push
(
node
);
}
else
{
effectSet
=
effectSet
.
concat
(
children
);
}
else
if
(
nodeType
===
"main"
)
{
Layout
.
align
=
"left"
;
if
(
action
===
"append"
||
action
===
"contract"
)
{
Layout
.
branchwidth
=
node
.
getRenderContainer
().
getWidth
()
+
nodeStyle
.
margin
[
1
]
+
nodeStyle
.
margin
[
3
];
}
else
if
(
action
===
"change"
)
{
Layout
.
branchheight
=
countBranchWidth
(
node
);
Layout
.
y
=
rootLayout
.
y
+
_root
.
getRenderContainer
().
getHeight
()
+
nodeStyles
.
root
.
margin
[
2
]
+
nodeStyles
.
main
.
margin
[
0
];
}
effectSet
=
updateLayoutMain
();
}
else
{
Layout
.
align
=
"left"
;
var
parentLayout
=
parent
.
getLayout
();
var
parentShape
=
parent
.
getRenderContainer
();
var
prt
=
node
.
getParent
()
||
parent
;
//自底向上更新祖先元素的branchwidth值
while
(
prt
)
{
if
(
action
===
"append"
)
{
if
(
parent
.
getType
()
===
"main"
)
{
Layout
.
x
=
nodeStyles
.
sub
.
margin
[
3
];
}
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
();
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
();
}
//自顶向下更新受影响一侧的y值
var
_buffer
=
[
root
];
while
(
_buffer
.
length
>
0
)
{
//自顶向下更新y
var
_buffer
=
[
prt
];
while
(
_buffer
.
length
!==
0
)
{
var
childrenC
=
_buffer
[
0
].
getChildren
();
_buffer
=
_buffer
.
concat
(
childrenC
);
var
_buffer0Layout
=
_buffer
[
0
].
getLayout
();
var
children
=
_buffer
[
0
].
getChildren
();
_buffer
=
_buffer
.
concat
(
children
);
var
sX
=
_buffer0Layout
.
x
-
_buffer0Layout
.
branchwidth
/
2
;
for
(
var
i
=
0
;
i
<
children
.
length
;
i
++
)
{
var
childLayout
=
children
[
i
].
getLayout
();
childLayout
.
x
=
sX
;
sX
+=
childLayout
.
branchwidth
;
var
_buffer0Style
=
nodeStyles
[
_buffer
[
0
].
getType
()
];
var
sY
;
if
(
_buffer
[
0
].
getType
()
===
"main"
)
sY
=
0
;
else
sY
=
_buffer0Layout
.
y
+
_buffer
[
0
].
getRenderContainer
().
getHeight
()
+
_buffer0Style
.
margin
[
2
];
for
(
var
s
=
0
;
s
<
childrenC
.
length
;
s
++
)
{
var
childLayoutC
=
childrenC
[
s
].
getLayout
();
var
childStyleC
=
nodeStyles
[
childrenC
[
s
].
getType
()
];
childLayoutC
.
y
=
sY
+
childStyleC
.
margin
[
0
];
sY
+=
childLayoutC
.
branchheight
;
}
effectSet
.
push
(
_buffer
[
0
]
);
_buffer
.
shift
();
...
...
@@ -265,7 +258,20 @@ KityMinder.registerModule( "LayoutBottom", function () {
var
align
=
Layout
.
align
;
var
_rectHeight
=
nodeShape
.
getHeight
();
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
)
);
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
);
};
var
updateConnectAndshIcon
=
function
(
node
)
{
...
...
@@ -273,73 +279,50 @@ KityMinder.registerModule( "LayoutBottom", function () {
var
Layout
=
node
.
getLayout
();
var
nodeStyle
=
nodeStyles
[
node
.
getType
()
];
var
connect
;
var
_root
=
minder
.
getRoot
();
var
_rootLayout
=
_root
.
getLayout
();
//更新连线
if
(
nodeType
===
"main"
)
{
if
(
!
Layout
.
connect
)
{
connect
=
Layout
.
connect
=
new
kity
.
Group
();
var
bezier
=
Layout
.
connect
.
bezier
=
new
kity
.
Bezier
();
var
circle
=
Layout
.
connect
.
circle
=
new
kity
.
Circle
();
connect
.
addShapes
(
[
bezier
,
circle
]
);
connect
=
Layout
.
connect
=
new
kity
.
Path
();
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
;
var
nodeShape
=
node
.
getRenderContainer
();
var
nodeClosurePoints
=
nodeShape
.
getRenderBox
().
closurePoints
;
var
sPos
;
var
endPos
;
if
(
Layout
.
appendside
===
"left"
)
{
sPos
=
new
kity
.
BezierPoint
(
rootX
-
30
,
nodeClosurePoints
[
2
].
y
+
nodeShape
.
getHeight
()
/
2
);
endPos
=
new
kity
.
BezierPoint
(
nodeClosurePoints
[
2
].
x
+
3
,
nodeClosurePoints
[
2
].
y
+
nodeShape
.
getHeight
()
/
2
);
}
else
{
sPos
=
new
kity
.
BezierPoint
(
rootX
+
30
,
nodeClosurePoints
[
3
].
y
+
nodeShape
.
getHeight
()
/
2
);
endPos
=
new
kity
.
BezierPoint
(
nodeClosurePoints
[
3
].
x
-
3
,
nodeClosurePoints
[
3
].
y
+
nodeShape
.
getHeight
()
/
2
);
}
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
);
var
sX
=
_rootLayout
.
x
;
var
sY
=
_rootLayout
.
y
+
_root
.
getRenderContainer
().
getHeight
();
var
transX
=
Layout
.
x
+
node
.
getRenderContainer
().
getWidth
()
/
2
;
var
transY
=
sY
+
nodeStyles
.
root
.
margin
[
2
];
connect
.
getDrawer
().
clear
()
.
moveTo
(
sX
,
sY
)
.
lineTo
(
sX
,
transY
)
.
lineTo
(
transX
,
transY
)
.
lineTo
(
transX
,
Layout
.
y
);
connect
.
stroke
(
nodeStyles
.
main
.
stroke
);
}
else
if
(
nodeType
===
"sub"
)
{
var
parent
=
node
.
getParent
();
var
parentLayout
=
parent
.
getLayout
();
if
(
!
Layout
.
connect
)
{
connect
=
Layout
.
connect
=
new
kity
.
Path
();
minder
.
getRenderContainer
()
.
addShape
(
connect
);
Layout
.
subgroup
.
addShape
(
connect
);
}
connect
=
Layout
.
connect
;
var
parentShape
=
node
.
getParent
().
getRenderContainer
();
var
parentBox
=
parentShape
.
getRenderBox
();
var
parentLayout
=
node
.
getParent
().
getLayout
();
var
parentStyle
=
nodeStyles
[
node
.
getParent
().
getType
()
];
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
);
var
ssX
,
ssY
;
if
(
parent
.
getType
()
===
"main"
)
{
ssX
=
10
;
ssY
=
0
;
}
else
{
sX
=
parentBox
.
closurePoints
[
0
].
x
+
parentStyle
.
margin
[
1
];
nodeX
=
Shape
.
getRenderBox
().
closurePoints
[
1
].
x
+
1
;
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
);
ssX
=
parentLayout
.
x
+
10
;
ssY
=
parentLayout
.
y
+
parent
.
getRenderContainer
().
getHeight
()
+
10
;
}
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
if
(
nodeType
!==
"root"
)
{
if
(
nodeType
!==
"root"
&&
node
.
getChildren
().
length
!==
0
)
{
if
(
!
Layout
.
shicon
)
{
Layout
.
shicon
=
new
ShIcon
(
node
);
}
...
...
@@ -355,21 +338,13 @@ KityMinder.registerModule( "LayoutBottom", function () {
switch
(
nodeType
)
{
case
"root"
:
case
"main"
:
case
"sub"
:
if
(
highlight
)
{
Layout
.
bgRect
.
fill
(
nodeStyle
.
highlight
);
}
else
{
Layout
.
bgRect
.
fill
(
nodeStyle
.
fill
);
}
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
:
break
;
}
...
...
@@ -383,13 +358,18 @@ KityMinder.registerModule( "LayoutBottom", function () {
},
false
)
);
updateShapeByCont
(
node
);
var
set1
=
updateLayoutHorizon
(
node
);
var
set2
=
updateLayoutVertical
(
node
,
node
.
getParent
(),
"change"
);
var
set
=
uSet
(
set1
,
set2
);
var
set
=
updateLayoutAll
(
node
,
node
.
getParent
(),
"change"
);
for
(
var
i
=
0
;
i
<
set
.
length
;
i
++
)
{
translateNode
(
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
()
{
var
_root
=
minder
.
getRoot
();
...
...
@@ -405,8 +385,7 @@ KityMinder.registerModule( "LayoutBottom", function () {
node
:
_root
},
false
)
);
updateShapeByCont
(
_root
);
updateLayoutHorizon
(
_root
);
updateLayoutVertical
(
_root
);
updateLayoutAll
(
_root
);
translateNode
(
_root
);
var
_buffer
=
[
_root
];
var
_cleanbuffer
=
[];
...
...
@@ -427,13 +406,22 @@ KityMinder.registerModule( "LayoutBottom", function () {
}
},
appendChildNode
:
function
(
parent
,
node
,
sibling
)
{
minder
.
handelNodeInsert
(
node
);
node
.
clearLayout
();
var
parentLayout
=
parent
.
getLayout
();
//设置分支类型
if
(
parent
.
getType
()
===
"root"
)
{
node
.
setType
(
"main"
);
minder
.
handelNodeInsert
(
node
);
}
else
{
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
);
...
...
@@ -445,22 +433,97 @@ KityMinder.registerModule( "LayoutBottom", function () {
node
:
node
},
false
)
);
updateShapeByCont
(
node
);
var
set2
=
updateLayoutHorizon
(
node
,
parent
,
"append"
);
var
set1
=
updateLayoutVertical
(
node
);
var
set
=
uSet
(
set1
,
set2
);
var
set
=
updateLayoutAll
(
node
,
parent
,
"append"
);
for
(
var
i
=
0
;
i
<
set
.
length
;
i
++
)
{
translateNode
(
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
)
{
var
parent
=
sibling
.
getParent
();
this
.
appendChildNode
(
parent
,
node
,
sibling
);
},
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
)
{
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
);
...
...
src/module/layout.default.js
View file @
6b25e103
...
...
@@ -605,7 +605,6 @@ KityMinder.registerModule( "LayoutDefault", function () {
var
parent
=
_buffer
[
0
].
getParent
();
Layout
.
parent
=
parent
;
_cleanbuffer
.
push
(
_buffer
[
0
]
);
//minder.appendChildNode( parent, _buffer[ 0 ] );
Layout
.
connect
=
null
;
Layout
.
shicon
=
null
;
}
else
{
...
...
src/module/layout.js
View file @
6b25e103
...
...
@@ -8,7 +8,11 @@ KityMinder.registerModule( "LayoutModule", function () {
return
this
.
_layoutStyles
[
name
];
},
getLayoutStyleItems
:
function
()
{
return
this
.
_layoutStyles
;
var
items
=
[];
for
(
var
key
in
this
.
_layoutStyles
)
{
items
.
push
(
key
);
}
return
items
;
},
getCurrentStyle
:
function
()
{
var
_root
=
this
.
getRoot
();
...
...
@@ -90,7 +94,10 @@ KityMinder.registerModule( "LayoutModule", function () {
var
SwitchLayoutCommand
=
kity
.
createClass
(
"SwitchLayoutCommand"
,
(
function
()
{
return
{
base
:
Command
,
execute
:
switchLayout
execute
:
switchLayout
,
queryValue
:
function
(
km
)
{
return
km
.
getCurrentStyle
();
}
};
}
)()
);
var
AppendChildNodeCommand
=
kity
.
createClass
(
"AppendChildNodeCommand"
,
(
function
()
{
...
...
@@ -98,12 +105,17 @@ KityMinder.registerModule( "LayoutModule", function () {
base
:
Command
,
execute
:
function
(
km
,
node
)
{
var
parent
=
km
.
getSelectedNode
();
if
(
!
parent
)
{
return
false
;
}
km
.
appendChildNode
(
parent
,
node
);
km
.
select
(
node
,
true
);
return
node
;
},
queryState
:
function
(
km
)
{
var
selectedNode
=
km
.
getSelectedNode
();
if
(
!
selectedNode
)
{
return
-
1
;
}
else
{
return
0
;
}
}
};
}
)()
);
...
...
@@ -112,9 +124,6 @@ KityMinder.registerModule( "LayoutModule", function () {
base
:
Command
,
execute
:
function
(
km
,
node
)
{
var
selectedNode
=
km
.
getSelectedNode
();
if
(
!
selectedNode
)
{
return
false
;
}
if
(
selectedNode
.
isRoot
()
)
{
node
.
setType
(
"main"
);
km
.
appendChildNode
(
selectedNode
,
node
);
...
...
@@ -124,6 +133,15 @@ KityMinder.registerModule( "LayoutModule", function () {
}
km
.
select
(
node
,
true
);
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 () {
execute
:
function
(
km
)
{
var
selectedNodes
=
km
.
getSelectedNodes
();
var
_root
=
km
.
getRoot
();
if
(
selectedNodes
.
length
===
0
||
(
selectedNodes
.
length
===
1
&&
!
selectedNodes
[
0
].
getParent
()
)
)
{
km
.
select
(
_root
);
return
false
;
}
var
_buffer
=
[];
for
(
var
i
=
0
;
i
<
selectedNodes
.
length
;
i
++
)
{
_buffer
.
push
(
selectedNodes
[
i
]
);
...
...
@@ -148,6 +162,14 @@ KityMinder.registerModule( "LayoutModule", function () {
}
while
(
_buffer
.
length
>
1
);
km
.
removeNode
(
selectedNodes
);
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 () {
}
},
"defaultOptions"
:
{
"defaultlayoutstyle"
:
"default"
"defaultlayoutstyle"
:
"default"
,
"node"
:
{
'appendsiblingnode'
:
'appendsiblingnode'
,
'appendchildnode'
:
'appendchildnode'
,
'removenode'
:
'removenode'
}
}
};
}
);
\ No newline at end of file
src/module/select.js
View file @
6b25e103
...
...
@@ -29,7 +29,9 @@ KityMinder.registerModule( "Select", function () {
startPosition
=
g
.
snapToSharp
(
e
.
getPosition
()
);
},
selectMove
:
function
(
e
)
{
if
(
minder
.
isTextEditStatus
()
)
{
return
;
}
if
(
!
startPosition
)
return
;
var
p1
=
startPosition
,
...
...
@@ -65,7 +67,7 @@ KityMinder.registerModule( "Select", function () {
// 计算选中范围
minder
.
getRoot
().
traverse
(
function
(
node
)
{
var
renderBox
=
node
.
getRenderContainer
().
getRenderBox
();
var
renderBox
=
node
.
getRenderContainer
().
getRenderBox
(
"top"
);
if
(
g
.
isBoxIntersect
(
renderBox
,
marquee
)
)
{
selectedNodes
.
push
(
node
);
}
...
...
@@ -80,7 +82,7 @@ KityMinder.registerModule( "Select", function () {
}
if
(
marqueeMode
)
{
marqueeShape
.
fadeOut
(
200
,
'ease'
,
0
,
function
()
{
if
(
marqueeShape
.
remove
)
marqueeShape
.
remove
();
if
(
marqueeShape
.
remove
)
marqueeShape
.
remove
();
}
);
marqueeMode
=
false
;
}
...
...
src/module/zoom.js
View file @
6b25e103
...
...
@@ -62,7 +62,7 @@ KityMinder.registerModule( 'Zoom', function () {
'zoom-out'
:
ZoomOutCommand
},
addShortcutKeys
:
{
"zoom-in"
:
"
+
"
,
//=
"zoom-in"
:
"
=
"
,
//=
"zoom-out"
:
"-"
//-
},
events
:
{
...
...
src/protocal/png.js
0 → 100644
View file @
6b25e103
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
src/ui/combobox.js
View file @
6b25e103
...
...
@@ -21,7 +21,7 @@
"<%if(autoRecord) {%>"
+
"<%for( var i=0, len = recordStack.length; i<len; 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>"
+
"<label class=
\"
<%=labelClassName%>
\"
style=
\"
<%=itemStyles[ index ]%>
\"
unselectable=
\"
on
\"
onmousedown=
\"
return false
\"
><%=items[index]%></label>"
+
"</li>"
+
...
...
@@ -31,7 +31,7 @@
"<%}%>"
+
"<%}%>"
+
"<%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>"
+
"<label class=
\"
<%=labelClassName%>
\"
style=
\"
<%=itemStyles[ i ]%>
\"
unselectable=
\"
on
\"
onmousedown=
\"
return false
\"
><%=label%></label>"
+
"</li>"
+
...
...
@@ -46,10 +46,13 @@
value
:
[],
comboboxName
:
''
,
selected
:
''
,
//初始禁用状态
disabled
:
{},
//自动记录
autoRecord
:
true
,
//最多记录条数
recordCount
:
5
recordCount
:
5
,
enabledRecord
:
true
},
init
:
function
(
options
){
...
...
@@ -87,6 +90,7 @@
initSelectItem
:
function
(){
var
me
=
this
,
options
=
me
.
data
(
"options"
),
labelClass
=
"."
+
labelClassName
;
me
.
root
().
delegate
(
'.'
+
itemClassName
,
'click'
,
function
(){
...
...
@@ -94,6 +98,10 @@
var
$li
=
$
(
this
),
index
=
$li
.
attr
(
'data-item-index'
);
if
(
options
.
disabled
[
index
]
)
{
return
false
;
}
me
.
trigger
(
'comboboxselect'
,
{
index
:
index
,
label
:
$li
.
find
(
labelClass
).
text
(),
...
...
@@ -126,11 +134,18 @@
*/
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
)
{
items
=
this
.
data
(
'options'
).
items
;
items
=
options
.
items
;
}
// 禁用
if
(
options
.
disabled
[
index
]
)
{
return
null
;
}
if
(
itemCount
==
0
)
{
...
...
@@ -149,6 +164,7 @@
this
.
trigger
(
'changebefore'
,
items
[
index
]
);
this
.
_update
(
index
);
this
.
trigger
(
'changeafter'
,
items
[
index
]
);
...
...
@@ -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 @@
_update
:
function
(
index
)
{
var
options
=
this
.
data
(
"options"
),
newStack
=
[],
newChilds
=
null
;
newStack
=
[];
if
(
this
.
data
(
'options'
).
enabledRecord
){
$
.
each
(
options
.
recordStack
,
function
(
i
,
item
){
if
(
item
!=
index
)
{
...
...
@@ -275,15 +350,24 @@
}
options
.
recordStack
=
newStack
;
}
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
()
);
newChilds
=
null
;
newStack
=
null
;
}
};
...
...
themes/default/css/comboboxmenu.css
View file @
6b25e103
...
...
@@ -19,6 +19,7 @@
.kmui-combobox-menu
.kmui-combobox-item
{
display
:
block
;
border
:
1px
solid
white
;
white-space
:
nowrap
;
}
.kmui-combobox-menu
.kmui-combobox-item-label
{
...
...
@@ -185,3 +186,12 @@
.kmui-combobox-paragraph
.kmui-combobox-item-6
.kmui-combobox-item-label
{
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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment