| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- define(function(require, exports, module) {
- var kity = require('../core/kity');
- var utils = require('../core/utils');
- var Minder = require('../core/minder');
- var MinderNode = require('../core/node');
- var Command = require('../core/command');
- var Module = require('../core/module');
- var Renderer = require('../core/render');
- Module.register('Select', function() {
- var minder = this;
- var rc = minder.getRenderContainer();
- // 在实例上渲染框选矩形、计算框选范围的对象
- var marqueeActivator = (function() {
- // 记录选区的开始位置(mousedown的位置)
- var startPosition = null;
- // 选区的图形
- var marqueeShape = new kity.Path();
- // 标记是否已经启动框选状态
- // 并不是 mousedown 发生之后就启动框选状态,而是检测到移动了一定的距离(MARQUEE_MODE_THRESHOLD)之后
- var marqueeMode = false;
- var MARQUEE_MODE_THRESHOLD = 10;
- return {
- selectStart: function(e) {
- // 只接受左键
- if (e.originEvent.button || e.originEvent.altKey) return;
- // 清理不正确状态
- if (startPosition) {
- return this.selectEnd();
- }
- startPosition = e.getPosition(rc).round();
- },
- selectMove: function(e) {
- if (minder.getStatus() == 'textedit') {
- return;
- }
- if (!startPosition) return;
- var p1 = startPosition,
- p2 = e.getPosition(rc);
- // 检测是否要进入选区模式
- if (!marqueeMode) {
- // 距离没达到阈值,退出
- if (kity.Vector.fromPoints(p1, p2).length() < MARQUEE_MODE_THRESHOLD) {
- return;
- }
- // 已经达到阈值,记录下来并且重置选区形状
- marqueeMode = true;
- rc.addShape(marqueeShape);
- marqueeShape
- .fill(minder.getStyle('marquee-background'))
- .stroke(minder.getStyle('marquee-stroke')).setOpacity(0.8).getDrawer().clear();
- }
- var marquee = new kity.Box(p1.x, p1.y, p2.x - p1.x, p2.y - p1.y),
- selectedNodes = [];
- // 使其犀利
- marquee.left = Math.round(marquee.left);
- marquee.top = Math.round(marquee.top);
- marquee.right = Math.round(marquee.right);
- marquee.bottom = Math.round(marquee.bottom);
- // 选区形状更新
- marqueeShape.getDrawer().pipe(function() {
- this.clear();
- this.moveTo(marquee.left, marquee.top);
- this.lineTo(marquee.right, marquee.top);
- this.lineTo(marquee.right, marquee.bottom);
- this.lineTo(marquee.left, marquee.bottom);
- this.close();
- });
- // 计算选中范围
- minder.getRoot().traverse(function(node) {
- var renderBox = node.getLayoutBox();
- if (!renderBox.intersect(marquee).isEmpty()) {
- selectedNodes.push(node);
- }
- });
- // 应用选中范围
- minder.select(selectedNodes, true);
- // 清除多余的东西
- window.getSelection().removeAllRanges();
- },
- selectEnd: function(e) {
- if (startPosition) {
- startPosition = null;
- }
- if (marqueeMode) {
- marqueeShape.fadeOut(200, 'ease', 0, function() {
- if (marqueeShape.remove) marqueeShape.remove();
- });
- marqueeMode = false;
- }
- }
- };
- })();
- var lastDownNode = null,
- lastDownPosition = null;
- return {
- 'init': function() {
- window.addEventListener('mouseup', function() {
- marqueeActivator.selectEnd();
- });
- },
- 'events': {
- 'mousedown': function(e) {
- var downNode = e.getTargetNode();
- // 没有点中节点:
- // 清除选中状态,并且标记选区开始位置
- if (!downNode) {
- this.removeAllSelectedNodes();
- marqueeActivator.selectStart(e);
- this.setStatus('normal');
- }
- // 点中了节点,并且按了 shift 键:
- // 被点中的节点切换选中状态
- else if (e.isShortcutKey('Ctrl')) {
- this.toggleSelect(downNode);
- }
- // 点中的节点没有被选择:
- // 单选点中的节点
- else if (!downNode.isSelected()) {
- this.select(downNode, true);
- }
- // 点中的节点被选中了,并且不是单选:
- // 完成整个点击之后需要使其变为单选。
- // 不能马上变为单选,因为可能是需要拖动选中的多个节点
- else if (!this.isSingleSelect()) {
- lastDownNode = downNode;
- lastDownPosition = e.getPosition();
- }
- },
- 'mousemove': marqueeActivator.selectMove,
- 'mouseup': function(e) {
- var upNode = e.getTargetNode();
- // 如果 mouseup 发生在 lastDownNode 外,是无需理会的
- if (upNode && upNode == lastDownNode) {
- var upPosition = e.getPosition();
- var movement = kity.Vector.fromPoints(lastDownPosition, upPosition);
- if (movement.length() < 1) this.select(lastDownNode, true);
- lastDownNode = null;
- }
- // 清理一下选择状态
- marqueeActivator.selectEnd(e);
- },
- //全选操作
- 'normal.keydown': function(e) {
- if (e.isShortcutKey('ctrl+a')) {
- var selectedNodes = [];
- this.getRoot().traverse(function(node) {
- selectedNodes.push(node);
- });
- this.select(selectedNodes, true);
- e.preventDefault();
- }
- }
- }
- };
- });
- });
|