var React = require('react'); var Tree = require('./Tree'); var Node = require('./Node'); import styles from './Tree.scss'; module.exports = React.createClass({ displayName: 'UITree', propTypes: { tree: React.PropTypes.object.isRequired, paddingLeft: React.PropTypes.number, onCollapse: React.PropTypes.func, allowUpdates: React.PropTypes.bool, }, getDefaultProps() { return { paddingLeft: 20 }; }, getInitialState() { return this.init(this.props); }, componentWillReceiveProps(nextProps) { if(!this._updated) this.setState(this.init(nextProps)); else this._updated = false; }, init(props) { var tree = new Tree(props.tree); tree.isNodeCollapsed = props.isNodeCollapsed; tree.changeNodeCollapsed = props.changeNodeCollapsed; tree.updateNodesPosition(); return { tree: tree, dragging: { id: null, x: null, y: null, w: null, h: null } }; }, getDraggingDom() { var tree = this.state.tree; var dragging = this.state.dragging; if(dragging && dragging.id) { var draggingIndex = tree.getIndex(dragging.id); var draggingStyles = { top: dragging.y, left: dragging.x, width: dragging.w }; return (
); } return null; }, render() { var tree = this.state.tree; var dragging = this.state.dragging; var draggingDom = this.getDraggingDom(); return (
{ draggingDom }
); }, dragStart(id, dom, e) { this.dragging = { id: id, w: dom.offsetWidth, h: dom.offsetHeight, x: dom.offsetLeft, y: dom.offsetTop }; this._startX = dom.offsetLeft; this._startY = dom.offsetTop; this._offsetX = e.clientX; this._offsetY = e.clientY; this._start = true; window.addEventListener('mousemove', this.drag); window.addEventListener('mouseup', this.dragEnd); }, // oh drag(e) { if(this._start) { this.setState({ dragging: this.dragging }); this._start = false; } var tree = this.state.tree; var dragging = this.state.dragging; var paddingLeft = this.props.paddingLeft; var newIndex = null; var index = tree.getIndex(dragging.id); var collapsed = index.node.collapsed; var _startX = this._startX; var _startY = this._startY; var _offsetX = this._offsetX; var _offsetY = this._offsetY; var pos = { x: _startX + e.clientX - _offsetX, y: _startY + e.clientY - _offsetY }; dragging.x = pos.x; dragging.y = pos.y; var diffX = dragging.x - paddingLeft/2 - (index.left-2) * paddingLeft; var diffY = dragging.y - dragging.h/2 - (index.top-2) * dragging.h; if(diffX < 0) { // left if(index.parent && !index.next) { newIndex = tree.move(index.id, index.parent, 'after'); } } else if(diffX > paddingLeft) { // right if(index.prev) { var prevNode = tree.getIndex(index.prev).node; if(!prevNode.collapsed && !prevNode.leaf) { newIndex = tree.move(index.id, index.prev, 'append'); } } } if(newIndex) { index = newIndex; newIndex.node.collapsed = collapsed; dragging.id = newIndex.id; } if(diffY < 0) { // up var above = tree.getNodeByTop(index.top-1); newIndex = tree.move(index.id, above.id, 'before'); } else if(diffY > dragging.h) { // down if(index.next) { var below = tree.getIndex(index.next); if(below.children && below.children.length && !below.node.collapsed) { newIndex = tree.move(index.id, index.next, 'prepend'); } else { newIndex = tree.move(index.id, index.next, 'after'); } } else { var below = tree.getNodeByTop(index.top+index.height); if(below && below.parent !== index.id) { if(below.children && below.children.length) { newIndex = tree.move(index.id, below.id, 'prepend'); } else { newIndex = tree.move(index.id, below.id, 'after'); } } } } if(newIndex) { newIndex.node.collapsed = collapsed; dragging.id = newIndex.id; } this.setState({ tree: tree, dragging: dragging }); }, dragEnd() { this.setState({ dragging: { id: null, x: null, y: null, w: null, h: null } }); this.change(this.state.tree); window.removeEventListener('mousemove', this.drag); window.removeEventListener('mouseup', this.dragEnd); }, change(tree) { this._updated = true; if(this.props.onChange) this.props.onChange(tree.obj); }, toggleCollapse(nodeId) { var tree = this.state.tree; var index = tree.getIndex(nodeId); var node = index.node; node.collapsed = !node.collapsed; tree.updateNodesPosition(); this.setState({ tree: tree }); if(this.props.onCollapse) this.props.onCollapse(node.id, node.collapsed); }, // buildTreeNumbering(tree) { // const numberBuilder = (index, node, parentNumbering) => { // let numbering = parentNumbering ? `${parentNumbering}.${index}` : index; // let children; // if (node.children) { // children = node.children.map((child, childIndex) => { // return numberBuilder(childIndex+1, child, numbering); // }); // } // const data = { // module: { // ...node.module, // index: numbering, // } // } // if (children) { // data.children = children; // } // return data; // }; // const newTree = {...tree}; // newTree.children = []; // tree.children.forEach((child, index) => { // newTree.children.push(numberBuilder(index+1, child)); // }) // return newTree; // } });