2
0

BaseNodeEditor.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. import { Node, ButtonInput, TitleElement, ContextMenu } from 'flow';
  2. import { exportJSON, onValidNode, getColorFromValue, getTypeFromValue, getColorFromType } from './NodeEditorUtils.js';
  3. export class BaseNodeEditor extends Node {
  4. constructor( name, value = null, width = 300 ) {
  5. super();
  6. const getObjectCallback = ( /*output = null*/ ) => {
  7. return this.value;
  8. };
  9. this.setWidth( width );
  10. this.outputLength = 1;
  11. const title = new TitleElement( name )
  12. .setObjectCallback( getObjectCallback )
  13. .setSerializable( false )
  14. .setOutput( this.outputLength );
  15. const contextButton = new ButtonInput().onClick( () => {
  16. context.open();
  17. } ).setIcon( 'ti ti-dots' );
  18. const onAddButtons = () => {
  19. context.removeEventListener( 'show', onAddButtons );
  20. context.add( new ButtonInput( 'Remove' ).setIcon( 'ti ti-trash' ).onClick( () => {
  21. this.dispose();
  22. } ) );
  23. if ( this.hasJSON() ) {
  24. this.context.add( new ButtonInput( 'Export' ).setIcon( 'ti ti-download' ).onClick( () => {
  25. exportJSON( this.exportJSON(), this.constructor.name );
  26. } ) );
  27. }
  28. context.add( new ButtonInput( 'Isolate' ).setIcon( 'ti ti-3d-cube-sphere' ).onClick( () => {
  29. this.context.hide();
  30. this.title.dom.dispatchEvent( new MouseEvent( 'dblclick' ) );
  31. } ) );
  32. };
  33. const context = new ContextMenu( this.dom );
  34. context.addEventListener( 'show', onAddButtons );
  35. this.title = title;
  36. if ( this.icon ) this.setIcon( 'ti ti-' + this.icon );
  37. this.contextButton = contextButton;
  38. this.context = context;
  39. title.addButton( contextButton );
  40. this.add( title );
  41. this.editor = null;
  42. this.value = value;
  43. this.onValidElement = onValidNode;
  44. this.updateOutputConnection();
  45. }
  46. getOutputType() {
  47. return getTypeFromValue( this.value );
  48. }
  49. getColor() {
  50. return ( getColorFromType( this.getOutputType() ) || '#777777' ) + 'BB';
  51. }
  52. hasJSON() {
  53. return this.value && typeof this.value.toJSON === 'function';
  54. }
  55. exportJSON() {
  56. return this.value.toJSON();
  57. }
  58. serialize( data ) {
  59. super.serialize( data );
  60. delete data.width;
  61. }
  62. deserialize( data ) {
  63. delete data.width;
  64. super.deserialize( data );
  65. }
  66. setEditor( value ) {
  67. this.editor = value;
  68. this.dispatchEvent( new Event( 'editor' ) );
  69. return this;
  70. }
  71. add( element ) {
  72. element.onValid( ( source, target ) => this.onValidElement( source, target ) );
  73. return super.add( element );
  74. }
  75. setName( value ) {
  76. this.title.setTitle( value );
  77. return this;
  78. }
  79. setIcon( value ) {
  80. this.title.setIcon( 'ti ti-' + value );
  81. return this;
  82. }
  83. getName() {
  84. return this.title.getTitle();
  85. }
  86. setOutputLength( value ) {
  87. this.outputLength = value;
  88. this.updateOutputConnection();
  89. return;
  90. }
  91. setObjectCallback( callback ) {
  92. this.title.setObjectCallback( callback );
  93. return this;
  94. }
  95. getObject( callback ) {
  96. return this.title.getObject( callback );
  97. }
  98. setColor( color ) {
  99. this.title.setColor( color );
  100. return this;
  101. }
  102. updateOutputConnection() {
  103. this.title.setOutputColor( getColorFromValue( this.value ) );
  104. this.title.setOutput( this.value ? this.outputLength : 0 );
  105. }
  106. invalidate() {
  107. this.title.dispatchEvent( new Event( 'connect' ) );
  108. }
  109. dispose() {
  110. this.setEditor( null );
  111. this.context.hide();
  112. super.dispose();
  113. }
  114. }