Commit 1be05c9b authored by techird's avatar techird

拖动和排序

parent 8f997604
...@@ -59,6 +59,7 @@ ...@@ -59,6 +59,7 @@
'module/nodetext.js', 'module/nodetext.js',
'module/hyperlink.js', 'module/hyperlink.js',
'module/expand.js', 'module/expand.js',
'module/arrange.js',
'ui/jquery-ui-1.10.4.custom.min.js', 'ui/jquery-ui-1.10.4.custom.min.js',
'ui/widget.js', 'ui/widget.js',
'ui/button.js', 'ui/button.js',
......
...@@ -58,7 +58,6 @@ ...@@ -58,7 +58,6 @@
<a href="https://github.com/fex-team/kityminder/issues/new" target="_blank">Bug</a> | <a href="https://github.com/fex-team/kityminder/issues/new" target="_blank">Bug</a> |
<a href="mailto:kity@baidu.com" target="_blank">Contact Us</a> <a href="mailto:kity@baidu.com" target="_blank">Contact Us</a>
</p> </p>
<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdMini":"2","bdMiniList":[],"bdPic":"","bdStyle":"1","bdSize":"32"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
</body> </body>
<script> <script>
// create km instance // create km instance
......
Subproject commit 437d9c160a7961a3843cce3d9e2b01f64090f0df Subproject commit 0d9f7dcd784436d13e45b4570ce690e186f3c686
var keymap = KityMinder.keymap = { var keymap = KityMinder.keymap = (function(origin) {
var ret = {};
for (var key in origin) {
if (origin.hasOwnProperty(key)) {
ret[key] = origin[key];
ret[key.toLowerCase()] = origin[key];
}
}
return ret;
})({
'Backspace': 8, 'Backspace': 8,
'Tab': 9, 'Tab': 9,
'Enter': 13, 'Enter': 13,
...@@ -37,7 +46,7 @@ var keymap = KityMinder.keymap = { ...@@ -37,7 +46,7 @@ var keymap = KityMinder.keymap = {
'=': 187, '=': 187,
'-': 189, '-': 189,
"b": 66, 'b': 66,
'i': 73, 'i': 73,
//回退 //回退
'z': 90, 'z': 90,
...@@ -68,7 +77,7 @@ var keymap = KityMinder.keymap = { ...@@ -68,7 +77,7 @@ var keymap = KityMinder.keymap = {
38: 1, 38: 1,
39: 1, 39: 1,
40: 1, 40: 1,
113:1 113: 1
}, },
'isSelectedNodeKey': { 'isSelectedNodeKey': {
//上下左右 //上下左右
...@@ -79,4 +88,4 @@ var keymap = KityMinder.keymap = { ...@@ -79,4 +88,4 @@ var keymap = KityMinder.keymap = {
13: 1, 13: 1,
9: 1 9: 1
} }
}; });
\ No newline at end of file \ No newline at end of file
...@@ -30,6 +30,18 @@ kity.extendClass(MinderNode, { ...@@ -30,6 +30,18 @@ kity.extendClass(MinderNode, {
return layout; return layout;
}, },
getOrder: function() {
return this.getData('order') || this.getIndex();
},
setOrder: function(order) {
return this.setData('order', order);
},
getOrderHint: function(refer) {
return this.getLayoutInstance().getOrderHint(this);
},
getLayoutInstance: function() { getLayoutInstance: function() {
var LayoutClass = KityMinder._layout[this.getLayout()]; var LayoutClass = KityMinder._layout[this.getLayout()];
var layout = new LayoutClass(); var layout = new LayoutClass();
...@@ -89,10 +101,10 @@ kity.extendClass(MinderNode, { ...@@ -89,10 +101,10 @@ kity.extendClass(MinderNode, {
}, },
setLayoutOffset: function(p) { setLayoutOffset: function(p) {
this.setData('layout_' + this.getLayout() + '_offset', { this.setData('layout_' + this.getLayout() + '_offset', p ? {
x: p.x, x: p.x,
y: p.y y: p.y
}); } : null);
return this; return this;
}, },
...@@ -291,5 +303,9 @@ var Layout = kity.createClass('Layout', { ...@@ -291,5 +303,9 @@ var Layout = kity.createClass('Layout', {
box = g.mergeBox(box, matrix.transformBox(treeBox)); box = g.mergeBox(box, matrix.transformBox(treeBox));
} }
return box; return box;
},
getOrderHint: function(node) {
return [];
} }
}); });
\ No newline at end of file
...@@ -293,19 +293,22 @@ var MinderNode = KityMinder.MinderNode = kity.createClass('MinderNode', { ...@@ -293,19 +293,22 @@ var MinderNode = KityMinder.MinderNode = kity.createClass('MinderNode', {
}); });
MinderNode.getCommonAncestor = function(nodeA, nodeB) { MinderNode.getCommonAncestor = function(nodeA, nodeB) {
if (nodeA instanceof Array) {
return MinderNode.getCommonAncestor.apply(this, nodeA);
}
switch (arguments.length) { switch (arguments.length) {
case 1: case 1:
return nodeA; return nodeA.parent;
case 2: case 2:
if (nodeA.contains(nodeB)) { if (nodeA.isAncestorOf(nodeB)) {
return nodeA; return nodeA;
} }
if (nodeB.contains(nodeA)) { if (nodeB.isAncestorOf(nodeA)) {
return nodeB; return nodeB;
} }
var ancestor = nodeA.parent; var ancestor = nodeA.parent;
while (ancestor && !ancestor.contains(nodeB)) { while (ancestor && !ancestor.isAncestorOf(nodeB)) {
ancestor = ancestor.parent; ancestor = ancestor.parent;
} }
return ancestor; return ancestor;
......
...@@ -13,7 +13,7 @@ KityMinder.registerConnectProvider('default', function(node, parent, connection) ...@@ -13,7 +13,7 @@ KityMinder.registerConnectProvider('default', function(node, parent, connection)
var start, end, vector; var start, end, vector;
var abs = Math.abs; var abs = Math.abs;
var pathData = []; var pathData = [];
var side = box.cx > pBox.cx ? 'right' : 'left'; var side = node.getLayoutVector().x > 0 ? 'right' : 'left';
node.getMinder().getPaper().addResource(connectMarker); node.getMinder().getPaper().addResource(connectMarker);
...@@ -38,30 +38,24 @@ KityMinder.registerConnectProvider('default', function(node, parent, connection) ...@@ -38,30 +38,24 @@ KityMinder.registerConnectProvider('default', function(node, parent, connection)
var radius = node.getStyle('connect-radius'); var radius = node.getStyle('connect-radius');
var underY = box.bottom + 2; var underY = box.bottom + 2;
var p1, p2, p3, p4, v12; var startY = parent.getType() == 'sub' ? pBox.bottom + 2 : pBox.cy;
var isTop = parent.children.length > 1 && node.getIndex() === 0; var p1, p2, p3, mx;
if (side == 'right') { if (side == 'right') {
p1 = new kity.Point(pBox.right + parent.getStyle('margin-right'), pBox.cy); p1 = new kity.Point(pBox.right + 10, startY);
p3 = new kity.Point(box.left, underY); p2 = new kity.Point(box.left, underY);
p4 = new kity.Point(box.right, underY); p3 = new kity.Point(box.right + 10.5, underY);
p2 = p3.offset(-radius, isTop ? radius : -radius);
} else { } else {
p1 = new kity.Point(pBox.left - parent.getStyle('margin-left'), pBox.cy); p1 = new kity.Point(pBox.left - 10, startY);
p3 = new kity.Point(box.right, underY); p2 = new kity.Point(box.right, underY);
p4 = new kity.Point(box.left, underY); p3 = new kity.Point(box.left - 10.5, underY);
p2 = p3.offset(radius, isTop ? radius : -radius);
} }
v12 = kity.Vector.fromPoints(p1, p2); mx = (p1.x + p2.x) / 2;
pathData.push('M', p1); pathData.push('M', p1);
//pathData.push('L', p2); pathData.push('C', mx, p1.y, mx, p2.y, p2);
// rx, ry, xr, laf, sf, p
var sf = +(side == 'right' && isTop || side == 'left' && !isTop);
pathData.push('L', p3); pathData.push('L', p3);
pathData.push('L', p4);
//var ex = side == 'right' ? (start.x + radius) : (start.x - radius);
connection.setMarker(null); connection.setMarker(null);
......
...@@ -78,11 +78,13 @@ KityMinder.registerLayout('default', kity.createClass({ ...@@ -78,11 +78,13 @@ KityMinder.registerLayout('default', kity.createClass({
x = nodeContentBox.right - childContentBox.left; x = nodeContentBox.right - childContentBox.left;
x += parent.getStyle('margin-right') + child.getStyle('margin-left'); x += parent.getStyle('margin-right') + child.getStyle('margin-left');
// 设置布局矢量
child.setLayoutVector(new kity.Vector(childContentBox.right, childContentBox.cy)); child.setLayoutVector(new kity.Vector(childContentBox.right, childContentBox.cy));
} else { } else {
x = nodeContentBox.left - childContentBox.right; x = nodeContentBox.left - childContentBox.right;
x -= parent.getStyle('margin-left') + child.getStyle('margin-right'); x -= parent.getStyle('margin-left') + child.getStyle('margin-right');
// 设置布局矢量
child.setLayoutVector(new kity.Vector(childContentBox.left, childContentBox.cy)); child.setLayoutVector(new kity.Vector(childContentBox.left, childContentBox.cy));
} }
...@@ -93,6 +95,7 @@ KityMinder.registerLayout('default', kity.createClass({ ...@@ -93,6 +95,7 @@ KityMinder.registerLayout('default', kity.createClass({
y += children[i].getStyle('margin-top'); y += children[i].getStyle('margin-top');
} }
// 设置布局结果
transform = new kity.Matrix().translate(x, y); transform = new kity.Matrix().translate(x, y);
child.setLayoutTransform(transform); child.setLayoutTransform(transform);
...@@ -110,32 +113,34 @@ KityMinder.registerLayout('default', kity.createClass({ ...@@ -110,32 +113,34 @@ KityMinder.registerLayout('default', kity.createClass({
} }
}, },
getLayoutContextPoints: function(node) { getOrderHint: function(node) {
var points = []; var hint = [];
var siblings = node.parent && node.parent.children; var box = node.getLayoutBox();
var g = KityMinder.Geometry; var offset = node.getLevel() > 1 ? 3 : 5;
if (!siblings) return points; hint.push({
type: 'up',
siblings.forEach(function(sibling) { node: node,
if (sibling == node) return; area: {
var index = sibling.getIndex(); x: box.x,
var box = node.getLayoutBox(); y: box.top - node.getStyle('margin-top') - offset,
width: box.width,
// top order hint height: node.getStyle('margin-top')
points.push({ },
type: 'order', path: ['M', box.x, box.top - offset, 'L', box.right, box.top - offset]
index: index,
area: {
x: box.x,
y: box.top - 2,
width: box.width,
height: node.getStyle('margin-top')
},
hint: ['M', ]
});
}); });
return points; hint.push({
type: 'down',
node: node,
area: {
x: box.x,
y: box.bottom + offset,
width: box.width,
height: node.getStyle('margin-bottom')
},
path: ['M', box.x, box.bottom + offset, 'L', box.right, box.bottom + offset]
});
return hint;
} }
})); }));
\ No newline at end of file
kity.extendClass(MinderNode, {
arrange: function(index) {
var parent = this.parent;
if (!parent) return;
var sibling = parent.children;
if (index < 0 || index >= sibling.length) return;
sibling.splice(this.getIndex(), 1);
sibling.splice(index, 0, this);
return this;
}
});
function asc(nodeA, nodeB) {
return nodeA.getIndex() - nodeB.getIndex();
}
function desc(nodeA, nodeB) {
return -asc(nodeA, nodeB);
}
var ArrangeUpCommand = kity.createClass('ArrangeUpCommand', {
base: Command,
execute: function(km) {
var nodes = km.getSelectedNodes();
nodes.sort(asc);
var lastIndexes = nodes.map(function(node) {
return node.getIndex();
});
nodes.forEach(function(node, index) {
node.arrange(lastIndexes[index] - 1);
});
km.layout(300);
}
});
var ArrangeDownCommand = kity.createClass('ArrangeUpCommand', {
base: Command,
execute: function(km) {
var nodes = km.getSelectedNodes();
nodes.sort(desc);
var lastIndexes = nodes.map(function(node) {
return node.getIndex();
});
nodes.forEach(function(node, index) {
node.arrange(lastIndexes[index] + 1);
});
km.layout(300);
}
});
var ArrangeCommand = kity.createClass('ArrangeCommand', {
base: Command,
execute: function(km, nodes, index) {
nodes = nodes && nodes.slice() || km.getSelectedNodes().slice();
if (!nodes.length) return;
var ancestor = MinderNode.getCommonAncestor(nodes);
if (ancestor != nodes[0].parent) return;
var indexed = nodes.map(function(node) {
return {
index: node.getIndex(),
node: node
};
});
var asc = Math.min.apply(Math, indexed.map(function(one) { return one.index; })) >= index;
indexed.sort(function(a, b) {
return asc ? (b.index - a.index) : (a.index - b.index);
});
indexed.forEach(function(one) {
one.node.arrange(index);
});
km.layout(300);
}
});
KityMinder.registerModule('ArrangeModule', {
commands: {
'arrangeup': ArrangeUpCommand,
'arrangedown': ArrangeDownCommand,
'arrange': ArrangeCommand
},
addShortcutKeys: {
'arrangeup': 'alt+Up',
'arrangedown': 'alt+Down'
}
});
\ No newline at end of file
This diff is collapsed.
...@@ -84,16 +84,24 @@ KityMinder.Geometry = (function() { ...@@ -84,16 +84,24 @@ KityMinder.Geometry = (function() {
}; };
g.isPointInsideBox = function(p, b) { g.isPointInsideBox = function(p, b) {
uniformBox(b);
var ranges = g.getBoxRange(b); var ranges = g.getBoxRange(b);
return g.isNumberInRange(p.x, ranges.x) && g.isNumberInRange(p.y, ranges.y); return g.isNumberInRange(p.x, ranges.x) && g.isNumberInRange(p.y, ranges.y);
}; };
g.isBoxIntersect = function(b1, b2) { g.getIntersectBox = function(b1, b2) {
uniformBox(b1);
uniformBox(b2);
var minx = max(b1.left, b2.left), var minx = max(b1.left, b2.left),
miny = max(b1.top, b2.top), miny = max(b1.top, b2.top),
maxx = min(b1.right, b2.right), maxx = min(b1.right, b2.right),
maxy = min(b1.bottom, b2.bottom); maxy = min(b1.bottom, b2.bottom);
return minx < maxx && miny < maxy; return minx < maxx && miny < maxy ? wrapBox({
left: minx,
right: maxx,
top: miny,
bottom: maxy
}) : null;
}; };
g.snapToSharp = function(unknown) { g.snapToSharp = function(unknown) {
......
...@@ -9,7 +9,7 @@ KityMinder.registerModule("KeyboardModule", function() { ...@@ -9,7 +9,7 @@ KityMinder.registerModule("KeyboardModule", function() {
var pointIndexes = [], var pointIndexes = [],
p; p;
root.traverse(function(node) { root.traverse(function(node) {
p = node.getRenderContainer().getRenderBox('top'); p = node.getLayoutBox();
// bugfix: 不应导航到收起的节点(判断其尺寸是否存在) // bugfix: 不应导航到收起的节点(判断其尺寸是否存在)
if (p.width && p.height) { if (p.width && p.height) {
...@@ -127,11 +127,10 @@ KityMinder.registerModule("KeyboardModule", function() { ...@@ -127,11 +127,10 @@ KityMinder.registerModule("KeyboardModule", function() {
km.select(nextNode, true); km.select(nextNode, true);
} }
} }
return { return {
'events': { 'events': {
'contentchange': function() { 'contentchange layoutfinish': function() {
buildPositionNetwork(this.getRoot()); buildPositionNetwork(this.getRoot());
}, },
'normal.keydown': function(e) { 'normal.keydown': function(e) {
...@@ -142,7 +141,11 @@ KityMinder.registerModule("KeyboardModule", function() { ...@@ -142,7 +141,11 @@ KityMinder.registerModule("KeyboardModule", function() {
this.receiver.keydownNode = node; this.receiver.keydownNode = node;
switch (e.originEvent.keyCode) { var keyEvent = e.originEvent;
if (keyEvent.altKey || keyEvent.ctrlKey || keyEvent.metaKey || keyEvent.shiftKey) return;
switch (keyEvent.keyCode) {
case keys.Enter: case keys.Enter:
this.execCommand('AppendSiblingNode', lang.topic); this.execCommand('AppendSiblingNode', lang.topic);
e.preventDefault(); e.preventDefault();
......
KityMinder.registerModule("Select", function() { KityMinder.registerModule('Select', function() {
var minder = this; var minder = this;
var g = KityMinder.Geometry; var g = KityMinder.Geometry;
...@@ -67,8 +67,8 @@ KityMinder.registerModule("Select", function() { ...@@ -67,8 +67,8 @@ KityMinder.registerModule("Select", function() {
// 计算选中范围 // 计算选中范围
minder.getRoot().traverse(function(node) { minder.getRoot().traverse(function(node) {
var renderBox = node.getRenderContainer().getRenderBox("top"); var renderBox = node.getRenderContainer().getRenderBox('top');
if (g.isBoxIntersect(renderBox, marquee)) { if (g.getIntersectBox(renderBox, marquee)) {
selectedNodes.push(node); selectedNodes.push(node);
} }
}); });
...@@ -90,7 +90,7 @@ KityMinder.registerModule("Select", function() { ...@@ -90,7 +90,7 @@ KityMinder.registerModule("Select", function() {
}; };
})(); })();
var lastDownNode = null; var lastDownNode = null, lastDownPosition = null;
return { return {
'events': { 'events': {
'normal.mousedown textedit.mousedown': function(e) { 'normal.mousedown textedit.mousedown': function(e) {
...@@ -122,6 +122,7 @@ KityMinder.registerModule("Select", function() { ...@@ -122,6 +122,7 @@ KityMinder.registerModule("Select", function() {
// 不能马上变为单选,因为可能是需要拖动选中的多个节点 // 不能马上变为单选,因为可能是需要拖动选中的多个节点
else if (!this.isSingleSelect()) { else if (!this.isSingleSelect()) {
lastDownNode = downNode; lastDownNode = downNode;
lastDownPosition = e.getPosition(this.getRenderContainer());
} }
}, },
'normal.mousemove textedit.mousemove': marqueeActivator.selectMove, 'normal.mousemove textedit.mousemove': marqueeActivator.selectMove,
...@@ -130,7 +131,9 @@ KityMinder.registerModule("Select", function() { ...@@ -130,7 +131,9 @@ KityMinder.registerModule("Select", function() {
// 如果 mouseup 发生在 lastDownNode 外,是无需理会的 // 如果 mouseup 发生在 lastDownNode 外,是无需理会的
if (upNode && upNode == lastDownNode) { if (upNode && upNode == lastDownNode) {
this.select(lastDownNode, true); var upPosition = e.getPosition(this.getRenderContainer());
var movement = kity.Vector.fromPoints(lastDownPosition, upPosition);
if (movement.length() < 1) this.select(lastDownNode, true);
lastDownNode = null; lastDownNode = null;
} }
......
...@@ -13,7 +13,7 @@ KityMinder.registerTheme('default', { ...@@ -13,7 +13,7 @@ KityMinder.registerTheme('default', {
'main-stroke': 'none', 'main-stroke': 'none',
'main-font-size': 16, 'main-font-size': 16,
'main-padding': [6, 20], 'main-padding': [6, 20],
'main-margin': [30, 10], 'main-margin': 20,
'main-radius': 10, 'main-radius': 10,
'main-space': 5, 'main-space': 5,
...@@ -22,7 +22,7 @@ KityMinder.registerTheme('default', { ...@@ -22,7 +22,7 @@ KityMinder.registerTheme('default', {
'sub-stroke': 'white', 'sub-stroke': 'white',
'sub-font-size': 12, 'sub-font-size': 12,
'sub-padding': [5, 10], 'sub-padding': [5, 10],
'sub-margin': 10, 'sub-margin': [15, 20],
'sub-tree-margin': 30, 'sub-tree-margin': 30,
'sub-radius': 5, 'sub-radius': 5,
'sub-space': 5, 'sub-space': 5,
...@@ -31,5 +31,14 @@ KityMinder.registerTheme('default', { ...@@ -31,5 +31,14 @@ KityMinder.registerTheme('default', {
'connect-width': 2, 'connect-width': 2,
'connect-radius': 5, 'connect-radius': 5,
'selected-background': 'rgb(254, 219, 0)' 'selected-background': 'rgb(254, 219, 0)',
'drop-hint-color': 'yellow',
'sub-drop-hint-width': 2,
'main-drop-hint-width': 4,
'root-drop-hint-width': 4,
'order-hint-area-color': 'rgba(0, 255, 0, .5)',
'order-hint-path-color': '#0f0',
'order-hint-path-width': 2
}); });
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment