|
@@ -7,7 +7,9 @@ import FlowModalData from './modal-data' // NEW 15/02/2018
|
|
|
import HxContextMenu from '@/components/shared/hx-contextmenu'
|
|
|
import SvgDefs from './svgdefswrapper'
|
|
|
import utils from '@/utils/utils'
|
|
|
+import mat from '@/utils/mat'
|
|
|
|
|
|
+const affIdentity = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
|
|
|
export default {
|
|
|
name: 'FlowManager',
|
|
|
components: {FlowNode, FlowLink, FlowTriggerLink, FlowPanZoom, FlowModalData, HxContextMenu, SvgDefs},
|
|
@@ -17,7 +19,8 @@ export default {
|
|
|
},
|
|
|
data () {
|
|
|
return {
|
|
|
- panzoom: { x: 0, y: 0, zoom: 1 },
|
|
|
+ // panzoom: { x: 0, y: 0, zoom: 1 },
|
|
|
+ panzoomCTM: affIdentity,
|
|
|
dragging: null,
|
|
|
linking: false,
|
|
|
triggerLinking: false,
|
|
@@ -33,6 +36,14 @@ export default {
|
|
|
},
|
|
|
computed: {
|
|
|
...mapGetters('flow', ['registry', 'activity', 'nodeData', 'nodeById', 'nodeSelection']),
|
|
|
+ panzoomIdentity () {
|
|
|
+ for (let i = 0; i < 16; i++) {
|
|
|
+ if (this.panzoomCTM[i] !== affIdentity[i]) {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true
|
|
|
+ },
|
|
|
outputNode () {
|
|
|
const n = this.nodeData.nodes.find(n => n.src === 'Output')
|
|
|
return !!n
|
|
@@ -81,7 +92,7 @@ export default {
|
|
|
'NOTIFICATION_ADD',
|
|
|
'DOCUMENT_SYNC',
|
|
|
'NODE_RAISE', 'NODE_UPDATE', 'NODE_ADD', 'NODE_REMOVE', 'NODE_INSPECT', 'NODE_PROCESS', 'NODE_TRAIN',
|
|
|
- 'NODE_SELECTION_ADD', 'NODE_SELECTION_SET', 'NODE_SELECTION_CLEAR',
|
|
|
+ 'NODE_SELECTION_ADD', 'NODE_SELECTION_SET', 'NODE_SELECTION_REMOVE', 'NODE_SELECTION_CLEAR',
|
|
|
'LINK_ADD', 'LINK_REMOVE',
|
|
|
'TRIGGER_ADD', 'TRIGGER_REMOVE' ]),
|
|
|
|
|
@@ -108,7 +119,7 @@ export default {
|
|
|
if (ev.ctrlKey) {
|
|
|
ev.preventDefault()
|
|
|
ev.stopPropagation()
|
|
|
- this.select(this.nodeData.nodes)
|
|
|
+ this.NODE_SELECTION_SET(this.nodeData.nodes)
|
|
|
}
|
|
|
break
|
|
|
}
|
|
@@ -120,7 +131,7 @@ export default {
|
|
|
}
|
|
|
},
|
|
|
panzoomReset () {
|
|
|
- this.panzoom = {x: 0, y: 0, zoom: 1}
|
|
|
+ this.panzoomCTM = affIdentity
|
|
|
},
|
|
|
// XXX: Shrink this function
|
|
|
// and create some LinkAdd method
|
|
@@ -289,10 +300,10 @@ export default {
|
|
|
nodeInspect (nodeId, force) {
|
|
|
this.$emit('nodeInspect', nodeId, force)
|
|
|
},
|
|
|
-
|
|
|
nodePointerDown (ev, nodeId) {
|
|
|
document.activeElement && document.activeElement.blur()
|
|
|
const tnode = this.nodeById(nodeId)
|
|
|
+ // Confirm
|
|
|
if (ev.button === 1) {
|
|
|
this.NODE_REMOVE([tnode])
|
|
|
return
|
|
@@ -305,19 +316,36 @@ export default {
|
|
|
return
|
|
|
}
|
|
|
this.nodeInspect(tnode.id)
|
|
|
-
|
|
|
- let selectionAdd = true
|
|
|
- // Switch selection
|
|
|
- if (!this.nodeSelection[tnode.id] && !ev.ctrlKey) {
|
|
|
- selectionAdd = false
|
|
|
+ let selectionToggle = false
|
|
|
+ let prevSelection = Object.assign({}, this.nodeSelection)
|
|
|
+ let wasSelected = !!this.nodeSelection[tnode.id]
|
|
|
+ // Basically clear selection and selection the new one
|
|
|
+ // if the clicked node isn't selected
|
|
|
+ if (!wasSelected) {
|
|
|
+ this.NODE_SELECTION_SET([tnode])
|
|
|
+ }
|
|
|
+ if (ev.ctrlKey) {
|
|
|
+ selectionToggle = true
|
|
|
}
|
|
|
- this.select([tnode], selectionAdd)
|
|
|
this.NODE_RAISE(this.nodeSelection)
|
|
|
|
|
|
let curP = this.transformedPoint(ev.x, ev.y)
|
|
|
let clone = false
|
|
|
if (ev.ctrlKey && Object.keys(this.nodeSelection).length > 0) clone = true
|
|
|
utils.createDrag({
|
|
|
+ noDrag: (ev) => {
|
|
|
+ if (selectionToggle) {
|
|
|
+ if (wasSelected) {
|
|
|
+ this.NODE_SELECTION_REMOVE([tnode])
|
|
|
+ } else {
|
|
|
+ prevSelection[tnode.id] = tnode
|
|
|
+ this.NODE_SELECTION_SET(prevSelection)
|
|
|
+ }
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.NODE_SELECTION_SET([tnode])
|
|
|
+ },
|
|
|
+
|
|
|
drag: (ev) => {
|
|
|
if (!ev.ctrlKey) clone = false
|
|
|
/// /////////// IMPORTANT NEW ////////////////
|
|
@@ -368,7 +396,7 @@ export default {
|
|
|
}
|
|
|
}
|
|
|
// Check inner links
|
|
|
- this.select(newNodes)
|
|
|
+ this.NODE_SELECTION_SET(newNodes)
|
|
|
}
|
|
|
// DRAG operation
|
|
|
this.dragging = this.nodeSelection
|
|
@@ -410,9 +438,6 @@ export default {
|
|
|
// Updating nodes
|
|
|
this.NODE_UPDATE(nodeUpdate)
|
|
|
this.DOCUMENT_SYNC()
|
|
|
- },
|
|
|
- noDrag: (ev) => {
|
|
|
- this.dragging = null
|
|
|
}
|
|
|
})
|
|
|
},
|
|
@@ -448,9 +473,9 @@ export default {
|
|
|
this.NODE_ADD([newNode])
|
|
|
},
|
|
|
nodeProcess (nodeId) {
|
|
|
- const n = this.nodeById(nodeId)
|
|
|
- this.nodeInspect(n.id, true)
|
|
|
- this.NODE_PROCESS(n.id)
|
|
|
+ // const n = this.nodeById(nodeId)
|
|
|
+ this.nodeInspect(nodeId, true)
|
|
|
+ this.NODE_PROCESS([nodeId])
|
|
|
// this.NODE_SELECTION_SET([n])
|
|
|
// this.nodeSelectionProcess()
|
|
|
},
|
|
@@ -469,14 +494,15 @@ export default {
|
|
|
},
|
|
|
viewPointerDown (ev) {
|
|
|
if (ev.button !== 0) return
|
|
|
+ var svgElRect = this.$refs.svg.getBoundingClientRect()
|
|
|
ev.preventDefault()
|
|
|
- const p = this.transformedPoint(ev.x, ev.y)
|
|
|
+ const p = {x: ev.x - svgElRect.left, y: ev.y - svgElRect.top}// this.transformedPoint(ev.x, ev.y)
|
|
|
this.selector = {x: p.x, y: p.y, width: 0, height: 0}
|
|
|
utils.createDrag({
|
|
|
drag: (evd) => {
|
|
|
// transform again in case we changed zoom/pan
|
|
|
- const p = this.transformedPoint(ev.x, ev.y)
|
|
|
- const p2 = this.transformedPoint(evd.x, evd.y)
|
|
|
+ // const p = {x: ev.x, y: ev.y} // this.transformedPoint(ev.x, ev.y)
|
|
|
+ const p2 = {x: evd.x - svgElRect.left, y: evd.y - svgElRect.top} // this.transformedPoint(evd.x, evd.y)
|
|
|
const nwidth = p2.x - p.x
|
|
|
const nheight = p2.y - p.y
|
|
|
this.selector = {
|
|
@@ -492,18 +518,26 @@ export default {
|
|
|
const nodesToSelect = []
|
|
|
for (let n in this.nodeData.nodes) {
|
|
|
const node = this.nodeData.nodes[n]
|
|
|
- if (node.x > this.selector.x && node.x < (this.selector.x + this.selector.width) &&
|
|
|
- node.y > this.selector.y && node.y < (this.selector.y + this.selector.height)
|
|
|
+ // Transform backNodes
|
|
|
+ var nodeP = [node.x, node.y, 0]
|
|
|
+ nodeP = mat.multiplyPoint(this.panzoomCTM, nodeP)
|
|
|
+
|
|
|
+ if (nodeP[0] > this.selector.x && nodeP[0] < (this.selector.x + this.selector.width) &&
|
|
|
+ nodeP[1] > this.selector.y && nodeP[1] < (this.selector.y + this.selector.height)
|
|
|
) {
|
|
|
nodesToSelect.push(node)
|
|
|
// Add to selection
|
|
|
}
|
|
|
}
|
|
|
- this.select(nodesToSelect, selectionAdd)
|
|
|
+ if (selectionAdd) {
|
|
|
+ this.NODE_SELECTION_ADD(nodesToSelect)
|
|
|
+ } else {
|
|
|
+ this.NODE_SELECTION_SET(nodesToSelect)
|
|
|
+ }
|
|
|
this.selector = null
|
|
|
},
|
|
|
noDrag: (ev) => {
|
|
|
- if (!ev.shiftKey) this.select()
|
|
|
+ if (!ev.shiftKey) this.NODE_SELECTION_CLEAR()
|
|
|
}
|
|
|
})
|
|
|
},
|
|
@@ -540,14 +574,19 @@ export default {
|
|
|
|
|
|
this.NODE_ADD([portalNode])
|
|
|
},
|
|
|
- select (nodes, add) {
|
|
|
+
|
|
|
+ /* select (nodes, add) {
|
|
|
+ if (!nodes) {
|
|
|
+ this.NODE_SELECTION_CLEAR()
|
|
|
+ return
|
|
|
+ }
|
|
|
if (!add) {
|
|
|
this.NODE_SELECTION_CLEAR()
|
|
|
}
|
|
|
if (nodes) {
|
|
|
this.NODE_SELECTION_ADD(nodes)
|
|
|
}
|
|
|
- },
|
|
|
+ }, */
|
|
|
// HELPERS depending on svg ref
|
|
|
createSVGPoint (x, y) {
|
|
|
const p = this.$refs.svg.createSVGPoint()
|