editor.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. <template>
  2. <div class="flow-container">
  3. <svg
  4. xmlns="http://www.w3.org/2000/svg"
  5. xmlns:xlink="http://www.w3.org/1999/xlink"
  6. ref="svg"
  7. class="flow-view view"
  8. :class="viewClasses"
  9. @dragover.prevent
  10. @drop="managerDrop"
  11. @mousedown="viewPointerDown"
  12. :width="width"
  13. :height="height">
  14. <svg-defs/>
  15. <flow-pan-zoom
  16. ref="panzoom"
  17. v-model="panzoom">
  18. <!-- links below nodes -->
  19. <flow-link
  20. v-for="(link,i) in nodeData.links"
  21. :key="'link' + i"
  22. v-bind="linkProps(link)"
  23. @click="linkPointerClick($event,link)"
  24. />
  25. <!-- trigger links -->
  26. <flow-trigger-link
  27. v-for="(trigger,i) in nodeData.triggers"
  28. :key="'trigger'+i"
  29. label="WIP"
  30. v-bind="triggerProps(trigger)"
  31. @click="TRIGGER_REMOVE(trigger)"
  32. />
  33. <!-- nodes -->
  34. <flow-node
  35. ref="nodes"
  36. v-for="(n,i) of nodeData.nodes"
  37. v-bind="nodeProps(n)"
  38. :key="'node' + n.id"
  39. :id="n.id"
  40. :selected="nodeSelection[n.id]?true:false"
  41. @nodePointerDown.prevent="nodePointerDown($event,i)"
  42. @socketPointerDown="socketPointerDown(n.id,...arguments)"
  43. @triggerPointerDown="triggerPointerDown(n.id,...arguments)"
  44. @nodeDoubleClick="$emit('nodeDblClick',n)"
  45. @nodeRightClick="$refs.menu.open($event,n)"
  46. />
  47. <!-- mouse link-->
  48. <flow-link
  49. :pointer="true"
  50. v-if="pointerLink.active"
  51. v-bind="pointerLink.props"
  52. />
  53. <flow-trigger-link
  54. :pointer="true"
  55. v-if="pointerTriggerLink.active"
  56. v-bind="pointerTriggerLink.props"
  57. />
  58. <rect
  59. class="flow-selector"
  60. :class="{'flow-selector--selecting':(selector)?true:false}"
  61. v-bind="selector"/>
  62. </flow-pan-zoom>
  63. </svg>
  64. <div class="flow-container__control">
  65. <button @click="stickySockets=!stickySockets"> {{ stickySockets? 'Hide':'Show' }} sockets </button>
  66. <button @click="stickyTriggers=!stickyTriggers"> {{ stickyTriggers? 'Hide':'Show' }} triggers </button>
  67. <button @click="nodeActivity=!nodeActivity"> {{ nodeActivity? 'Hide':'Show' }} activity </button>
  68. <button @click="$emit('documentSave', nodeData)"> Save </button> <!-- should disable until confirmation -->
  69. <button v-if="panzoom.x!=0 || panzoom.y!=0 || panzoom.zoom!=1" @click="panzoomReset">
  70. Reset view
  71. </button>
  72. </div>
  73. <div class="flow-container__info">
  74. x:{{ panzoom.x.toFixed(2) }} y:{{ panzoom.y.toFixed(2) }} scale:{{ panzoom.zoom.toFixed(2) }}
  75. nodes: {{ nodeData.nodes.length }}
  76. links: {{ nodeData.links.length }}
  77. triggers: {{ nodeData.triggers.length }}
  78. </div>
  79. <hx-context-menu ref="menu">
  80. <template slot-scope="d" >
  81. <div class="flow-node__context-menu">
  82. <div class="hover" @click="nodeProcess(d.userData)">Run</div>
  83. <div class="hover" tabindex="0" @click="nodeRemove(d.userData)">Delete</div>
  84. <hr>
  85. <div class="hover" @click="nodeInspect(d.userData,true)">Inspect</div>
  86. </div>
  87. </template>
  88. </hx-context-menu>
  89. </div>
  90. </template>
  91. <script src="./editor.js">
  92. </script>
  93. <style>
  94. .flow-container {
  95. display:flex;
  96. flex-flow:row;
  97. position:relative;
  98. }
  99. .flow-container__control {
  100. position:absolute;
  101. top: 20px;
  102. left: 20px;
  103. display:flex;
  104. justify-content: center;
  105. align-items: center;
  106. color: #fff;
  107. }
  108. .flow-container__control button {
  109. display:flex;
  110. justify-content: center;
  111. margin:0;
  112. padding:14px;
  113. color:#333;
  114. }
  115. .flow-container__info {
  116. position:absolute;
  117. bottom:10px;
  118. left:10px;
  119. padding:2px;
  120. font-size:9px;
  121. }
  122. .flow-view {
  123. border:none;
  124. position:relative;
  125. fill:transparent;
  126. }
  127. .flow-selector {
  128. pointer-events:none;
  129. opacity:0;
  130. }
  131. .flow-selector.flow-selector--selecting {
  132. opacity:1;
  133. }
  134. .flow-node__context-menu {
  135. box-shadow: 0 1px 4px rgba(0,0,0,0.2);
  136. display:flex;
  137. flex-flow: column;
  138. justify-content: start;
  139. align-items: stretch;
  140. width:180px;
  141. }
  142. .flow-node__context-menu > div {
  143. padding:10px 20px;
  144. cursor: pointer;
  145. }
  146. .flow-node__context-menu > * {
  147. width:100%;
  148. }
  149. .flow-node__context-menu hr {
  150. width:90%;
  151. border:none;
  152. border-bottom: solid 1px rgba(150,150,150,0.2);
  153. }
  154. .flow-node__context-menu button {
  155. text-align:left;
  156. }
  157. </style>