lexgui 0.1.34 → 0.1.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,7 +8,7 @@
8
8
  */
9
9
 
10
10
  var LX = {
11
- version: "0.1.34",
11
+ version: "0.1.36",
12
12
  ready: false,
13
13
  components: [], // specific pre-build components
14
14
  signals: {} // events and triggers
@@ -41,43 +41,43 @@ function has( component_name )
41
41
 
42
42
  LX.has = has;
43
43
 
44
- function getExtension(s)
44
+ function getExtension( s )
45
45
  {
46
46
  return s.includes('.') ? s.split('.').pop() : null;
47
47
  }
48
48
 
49
49
  LX.getExtension = getExtension;
50
50
 
51
- function deepCopy(o)
51
+ function deepCopy( o )
52
52
  {
53
53
  return JSON.parse(JSON.stringify(o))
54
54
  }
55
55
 
56
56
  LX.deepCopy = deepCopy;
57
57
 
58
- function setThemeColor(color_name, color)
58
+ function setThemeColor( colorName, color )
59
59
  {
60
- var r = document.querySelector(':root');
61
- r.style.setProperty("--" + color_name, color);
60
+ var r = document.querySelector( ':root' );
61
+ r.style.setProperty( '--' + colorName, color );
62
62
  }
63
63
 
64
64
  LX.setThemeColor = setThemeColor;
65
65
 
66
- function getThemeColor(color_name)
66
+ function getThemeColor( colorName )
67
67
  {
68
- var r = getComputedStyle(document.querySelector(':root'));
69
- return r.getPropertyValue("--" + color_name);
68
+ var r = getComputedStyle( document.querySelector( ':root' ) );
69
+ return r.getPropertyValue( '--' + colorName );
70
70
  }
71
71
 
72
72
  LX.getThemeColor = getThemeColor;
73
73
 
74
- function getBase64Image(img) {
75
- var canvas = document.createElement("canvas");
74
+ function getBase64Image( img ) {
75
+ var canvas = document.createElement( 'canvas' );
76
76
  canvas.width = img.width;
77
77
  canvas.height = img.height;
78
- var ctx = canvas.getContext("2d");
79
- ctx.drawImage(img, 0, 0);
80
- return canvas.toDataURL("image/png");
78
+ var ctx = canvas.getContext( '2d' );
79
+ ctx.drawImage( img, 0, 0 );
80
+ return canvas.toDataURL( 'image/png' );
81
81
  }
82
82
 
83
83
  LX.getBase64Image = getBase64Image;
@@ -129,22 +129,26 @@ let ASYNC_ENABLED = true;
129
129
 
130
130
  function doAsync( fn, ms ) {
131
131
  if( ASYNC_ENABLED )
132
+ {
132
133
  setTimeout( fn, ms ?? 0 );
134
+ }
133
135
  else
136
+ {
134
137
  fn();
138
+ }
135
139
  }
136
140
 
137
141
  // Math classes
138
142
 
139
143
  class vec2 {
140
144
 
141
- constructor(x, y) {
145
+ constructor( x, y ) {
142
146
  this.x = x ?? 0;
143
- this.y = y ?? (x ?? 0);
147
+ this.y = y ?? ( x ?? 0 );
144
148
  }
145
149
 
146
- get xy() { return [ this.x, this.y]; }
147
- get yx() { return [ this.y, this.x]; }
150
+ get xy() { return [ this.x, this.y ]; }
151
+ get yx() { return [ this.y, this.x ]; }
148
152
 
149
153
  set ( x, y ) { this.x = x; this.y = y; }
150
154
  add ( v, v0 = new vec2() ) { v0.set( this.x + v.x, this.y + v.y ); return v0; }
@@ -152,6 +156,11 @@ class vec2 {
152
156
  mul ( v, v0 = new vec2() ) { if( v.constructor == Number ) { v = new vec2( v ) } v0.set( this.x * v.x, this.y * v.y ); return v0; }
153
157
  div ( v, v0 = new vec2() ) { if( v.constructor == Number ) { v = new vec2( v ) } v0.set( this.x / v.x, this.y / v.y ); return v0; }
154
158
  abs ( v0 = new vec2() ) { v0.set( Math.abs( this.x ), Math.abs( this.y ) ); return v0; }
159
+ dot ( v ) { return this.x * v.x + this.y * v.y; }
160
+ len2 () { return this.dot( this ) }
161
+ len () { return Math.sqrt( this.len2() ); }
162
+ nrm ( v0 = new vec2() ) { v0.set( this.x, this.y ); return v0.mul( 1.0 / this.len(), v0 ); }
163
+ dst ( v ) { return v.sub( this ).len(); }
155
164
  };
156
165
 
157
166
  LX.vec2 = vec2;
@@ -469,7 +478,7 @@ function init( options = { } )
469
478
  var link = document.createElement( 'link' );
470
479
  link.rel = 'stylesheet';
471
480
  link.type = 'text/css';
472
- link.href = 'https://use.fontawesome.com/releases/v6.5.1/css/all.css';
481
+ link.href = 'https://use.fontawesome.com/releases/v6.6.0/css/all.css';
473
482
  head.appendChild( link );
474
483
 
475
484
  // Global vars
@@ -523,26 +532,29 @@ LX.message = message;
523
532
  * size: (Array) [width, height]
524
533
  */
525
534
 
526
- function popup(text, title, options = {})
535
+ function popup( text, title, options = {} )
527
536
  {
528
- if(!text)
537
+ if( !text )
538
+ {
529
539
  throw("No message to show");
540
+ }
530
541
 
531
- options.size = options.size ?? ["auto", "auto"];
542
+ options.size = options.size ?? [ "auto", "auto" ];
532
543
  options.class = "lexpopup";
533
- const time = options.timeout || 3000;
534
544
 
535
- const dialog = new Dialog(title, p => {
536
- p.addTextArea(null, text, null, { disabled: true, fitHeight: true });
537
- }, options);
545
+ const time = options.timeout || 3000;
546
+ const dialog = new Dialog( title, p => {
547
+ p.addTextArea( null, text, null, { disabled: true, fitHeight: true } );
548
+ }, options );
538
549
 
539
- dialog.root.classList.add("fadein");
550
+ dialog.root.classList.add( 'fadein' );
540
551
  setTimeout(() => {
541
- dialog.root.classList.remove("fadein");
542
- dialog.root.classList.add("fadeout");
543
- }, time - 1000);
552
+ dialog.root.classList.remove( 'fadein' );
553
+ dialog.root.classList.add( 'fadeout' );
554
+ }, time - 1000 );
544
555
 
545
- setTimeout(dialog.close, time);
556
+ setTimeout( dialog.close, time );
557
+
546
558
  return dialog;
547
559
  }
548
560
 
@@ -561,36 +573,45 @@ LX.popup = popup;
561
573
  * required: Input has to be filled [true]. Default: false
562
574
  */
563
575
 
564
- function prompt(text, title, callback, options = {})
576
+ function prompt( text, title, callback, options = {} )
565
577
  {
566
578
  options.modal = true;
567
579
 
568
580
  let value = "";
569
581
 
570
- const dialog = new Dialog(title, p => {
571
- p.addTextArea(null, text, null, { disabled: true });
572
- if(options.input !== false)
573
- p.addText(null, options.input || value, (v) => value = v, {placeholder: "..."} );
574
- p.sameLine(2);
575
- p.addButton(null, options.accept || "OK", () => {
576
- if(options.required && value === '') {
582
+ const dialog = new Dialog( title, p => {
577
583
 
578
- text += text.includes("You must fill the input text.") ? "": "\nYou must fill the input text.";
579
- dialog.close() ;
580
- prompt(text, title, callback, options);
581
- }else {
584
+ p.addTextArea( null, text, null, { disabled: true, fitHeight: true } );
582
585
 
583
- callback.call(this, value);
584
- dialog.close() ;
586
+ if( options.input ?? true )
587
+ {
588
+ p.addText( null, options.input || value, v => value = v, { placeholder: "..." } );
589
+ }
590
+
591
+ p.sameLine( 2 );
592
+
593
+ p.addButton( null, options.accept || "OK", () => {
594
+ if( options.required && value === '' )
595
+ {
596
+ text += text.includes("You must fill the input text.") ? "": "\nYou must fill the input text.";
597
+ dialog.close();
598
+ prompt( text, title, callback, options );
599
+ }else
600
+ {
601
+ if( callback ) callback.call( this, value );
602
+ dialog.close();
585
603
  }
586
-
587
604
  }, { buttonClass: "accept" });
605
+
588
606
  p.addButton(null, "Cancel", () => {if(options.on_cancel) options.on_cancel(); dialog.close();} );
589
- }, options);
607
+
608
+ }, options );
590
609
 
591
610
  // Focus text prompt
592
- if(options.input !== false)
593
- dialog.root.querySelector('input').focus();
611
+ if( options.input ?? true )
612
+ {
613
+ dialog.root.querySelector( 'input' ).focus();
614
+ }
594
615
 
595
616
  return dialog;
596
617
  }
@@ -647,16 +668,22 @@ class TreeEvent {
647
668
 
648
669
  LX.TreeEvent = TreeEvent;
649
670
 
650
- function emit( signal_name, value, target )
671
+ function emit( signalName, value, options = {} )
651
672
  {
652
- const data = LX.signals[ signal_name ];
673
+ const data = LX.signals[ signalName ];
653
674
 
654
675
  if( !data )
655
676
  return;
656
677
 
678
+ const target = options.target;
679
+
657
680
  if( target )
658
681
  {
659
- if(target[signal_name]) target[signal_name].call(target, value);
682
+ if( target[ signalName ])
683
+ {
684
+ target[ signalName ].call( target, value );
685
+ }
686
+
660
687
  return;
661
688
  }
662
689
 
@@ -664,13 +691,16 @@ function emit( signal_name, value, target )
664
691
  {
665
692
  if( obj.constructor === Widget )
666
693
  {
667
- obj.set( value );
694
+ obj.set( value, options.skipCallback ?? true );
668
695
 
669
- if(obj.options && obj.options.callback)
670
- obj.options.callback(value, data);
671
- }else
696
+ if( obj.options && obj.options.callback )
697
+ {
698
+ obj.options.callback( value, data );
699
+ }
700
+ }
701
+ else
672
702
  {
673
- obj[signal_name].call(obj, value);
703
+ obj[ signalName ].call( obj, value );
674
704
  }
675
705
  }
676
706
  }
@@ -710,12 +740,16 @@ class Area {
710
740
 
711
741
  constructor( options = {} ) {
712
742
 
713
- var root = document.createElement('div');
743
+ var root = document.createElement( 'div' );
714
744
  root.className = "lexarea";
715
- if(options.id)
745
+ if( options.id )
746
+ {
716
747
  root.id = options.id;
717
- if(options.className)
748
+ }
749
+ if( options.className )
750
+ {
718
751
  root.className += " " + options.className;
752
+ }
719
753
 
720
754
  var width = options.width || "calc( 100% )";
721
755
  var height = options.height || "100%";
@@ -723,10 +757,14 @@ class Area {
723
757
  // This has default options..
724
758
  this.setLimitBox( options.minWidth, options.minHeight, options.maxWidth, options.maxHeight );
725
759
 
726
- if(width.constructor == Number)
760
+ if( width.constructor == Number )
761
+ {
727
762
  width += "px";
728
- if(height.constructor == Number)
763
+ }
764
+ if( height.constructor == Number )
765
+ {
729
766
  height += "px";
767
+ }
730
768
 
731
769
  root.style.width = width;
732
770
  root.style.height = height;
@@ -737,27 +775,32 @@ class Area {
737
775
  this.sections = [];
738
776
  this.panels = [];
739
777
 
740
- if(!options.no_append) {
778
+ if( !options.no_append )
779
+ {
741
780
  var lexroot = document.getElementById("lexroot");
742
781
  lexroot.appendChild( this.root );
743
782
  }
744
783
 
745
784
  let overlay = options.overlay;
746
785
 
747
- if(overlay)
786
+ if( overlay )
748
787
  {
749
788
  this.root.classList.add("overlay-" + overlay);
750
789
 
751
- if(options.left) {
790
+ if( options.left )
791
+ {
752
792
  this.root.style.left = options.left;
753
793
  }
754
- if(options.right) {
794
+ else if( options.right )
795
+ {
755
796
  this.root.style.right = options.right;
756
797
  }
757
- if(options.top) {
798
+ else if( options.top )
799
+ {
758
800
  this.root.style.top = options.top;
759
801
  }
760
- if(options.bottom) {
802
+ else if( options.bottom )
803
+ {
761
804
  this.root.style.bottom = options.bottom;
762
805
  }
763
806
 
@@ -769,97 +812,99 @@ class Area {
769
812
  root.classList.add("resizeable");
770
813
  }
771
814
 
772
- if(options.resize)
815
+ if( options.resize )
773
816
  {
774
817
  this.split_bar = document.createElement("div");
775
- let type = overlay == "left" || overlay == "right" ? "horizontal" : "vertical";
818
+ let type = (overlay == "left") || (overlay == "right") ? "horizontal" : "vertical";
776
819
  this.type = overlay;;
777
820
  this.split_bar.className = "lexsplitbar " + type;
778
- if(overlay == "right") {
821
+
822
+ if( overlay == "right" )
823
+ {
779
824
  this.split_bar.style.width = LX.DEFAULT_SPLITBAR_SIZE + "px";
780
- this.split_bar.style.left = -LX.DEFAULT_SPLITBAR_SIZE/2 + "px";
825
+ this.split_bar.style.left = -(LX.DEFAULT_SPLITBAR_SIZE / 2.0) + "px";
781
826
  }
782
- else if(overlay == "left") {
827
+ else if( overlay == "left" )
828
+ {
783
829
  let size = Math.min(document.body.clientWidth - LX.DEFAULT_SPLITBAR_SIZE, this.root.clientWidth);
784
830
  this.split_bar.style.width = LX.DEFAULT_SPLITBAR_SIZE + "px";
785
- this.split_bar.style.left = size + LX.DEFAULT_SPLITBAR_SIZE/2 + "px";
831
+ this.split_bar.style.left = size + (LX.DEFAULT_SPLITBAR_SIZE / 2.0) + "px";
786
832
  }
787
- else if (overlay == "top") {
833
+ else if( overlay == "top" )
834
+ {
788
835
  let size = Math.min(document.body.clientHeight - LX.DEFAULT_SPLITBAR_SIZE, this.root.clientHeight);
789
836
  this.split_bar.style.height = LX.DEFAULT_SPLITBAR_SIZE + "px";
790
- this.split_bar.style.top = size + LX.DEFAULT_SPLITBAR_SIZE/2 + "px";
837
+ this.split_bar.style.top = size + (LX.DEFAULT_SPLITBAR_SIZE / 2.0) + "px";
791
838
  }
792
- else if(overlay == "bottom") {
839
+ else if( overlay == "bottom" )
840
+ {
793
841
  this.split_bar.style.height = LX.DEFAULT_SPLITBAR_SIZE + "px";
794
- this.split_bar.style.top = -LX.DEFAULT_SPLITBAR_SIZE/2 + "px";
842
+ this.split_bar.style.top = -(LX.DEFAULT_SPLITBAR_SIZE / 2.0) + "px";
795
843
  }
796
844
 
797
845
  this.split_bar.addEventListener("mousedown", inner_mousedown);
798
- this.root.appendChild(this.split_bar);
846
+ this.root.appendChild( this.split_bar );
799
847
 
800
848
  var that = this;
801
- var last_pos = [0,0];
849
+ var last_pos = [ 0, 0 ];
802
850
 
803
- function inner_mousedown(e)
851
+ function inner_mousedown( e )
804
852
  {
805
853
  var doc = that.root.ownerDocument;
806
- doc.addEventListener("mousemove",inner_mousemove);
807
- doc.addEventListener("mouseup",inner_mouseup);
808
- last_pos[0] = e.x;
809
- last_pos[1] = e.y;
854
+ doc.addEventListener( 'mousemove', inner_mousemove );
855
+ doc.addEventListener( 'mouseup', inner_mouseup );
856
+ last_pos[ 0 ] = e.x;
857
+ last_pos[ 1 ] = e.y;
810
858
  e.stopPropagation();
811
859
  e.preventDefault();
812
- document.body.classList.add("nocursor");
813
- that.split_bar.classList.add("nocursor");
860
+ document.body.classList.add( 'nocursor' );
861
+ that.split_bar.classList.add( 'nocursor' );
814
862
  }
815
863
 
816
- function inner_mousemove(e)
864
+ function inner_mousemove( e )
817
865
  {
818
- switch(that.type) {
866
+ switch( that.type ) {
819
867
  case "right":
820
- var dt = (last_pos[0] - e.x);
821
- var size = (that.root.offsetWidth + dt);
868
+ var dt = ( last_pos[ 0 ] - e.x );
869
+ var size = ( that.root.offsetWidth + dt );
822
870
  that.root.style.width = size + "px";
823
871
  break;
824
-
825
872
  case "left":
826
- var dt = (last_pos[0] - e.x);
873
+ var dt = ( last_pos[ 0 ] - e.x );
827
874
  var size = Math.min(document.body.clientWidth - LX.DEFAULT_SPLITBAR_SIZE, (that.root.offsetWidth - dt));
828
875
  that.root.style.width = size + "px";
829
876
  that.split_bar.style.left = size + LX.DEFAULT_SPLITBAR_SIZE/2 + "px";
830
877
  break;
831
-
832
878
  case "top":
833
- var dt = (last_pos[1] - e.y);
879
+ var dt = ( last_pos[ 1 ] - e.y );
834
880
  var size = Math.min(document.body.clientHeight - LX.DEFAULT_SPLITBAR_SIZE, (that.root.offsetHeight - dt));
835
881
  that.root.style.height = size + "px";
836
882
  that.split_bar.style.top = size + LX.DEFAULT_SPLITBAR_SIZE/2 + "px";
837
883
  break;
838
-
839
884
  case "bottom":
840
- var dt = (last_pos[1] - e.y);
841
- var size = (that.root.offsetHeight + dt);
885
+ var dt = ( last_pos[ 1 ] - e.y );
886
+ var size = ( that.root.offsetHeight + dt );
842
887
  that.root.style.height = size + "px";
843
888
  break;
844
889
  }
845
890
 
846
- last_pos[0] = e.x;
847
- last_pos[1] = e.y;
891
+ last_pos[ 0 ] = e.x;
892
+ last_pos[ 1 ] = e.y;
848
893
  e.stopPropagation();
849
894
  e.preventDefault();
850
895
 
851
896
  // Resize events
852
- if(that.onresize)
897
+ if( that.onresize )
853
898
  that.onresize( that.root.getBoundingClientRect() );
854
899
  }
855
900
 
856
- function inner_mouseup(e)
901
+ function inner_mouseup( e )
857
902
  {
858
903
  var doc = that.root.ownerDocument;
859
- doc.removeEventListener("mousemove",inner_mousemove);
860
- doc.removeEventListener("mouseup",inner_mouseup);
861
- document.body.classList.remove("nocursor");
862
- that.split_bar.classList.remove("nocursor");
904
+ doc.removeEventListener( 'mousemove', inner_mousemove );
905
+ doc.removeEventListener( 'mouseup', inner_mouseup );
906
+ document.body.classList.remove( 'nocursor' );
907
+ that.split_bar.classList.remove( 'nocursor' );
863
908
  }
864
909
  }
865
910
  }
@@ -896,35 +941,36 @@ class Area {
896
941
 
897
942
  split( options = {} ) {
898
943
 
899
- if(this.sections.length)
944
+ if( this.sections.length )
900
945
  {
901
946
  // In case Area has been split before, get 2nd section as root
902
- this.offset = this.root.childNodes[0].offsetHeight; // store offset to take into account when resizing
903
- this._root = this.sections[0].root;
904
- this.root = this.sections[1].root;
947
+ this.offset = this.root.childNodes[ 0 ].offsetHeight; // store offset to take into account when resizing
948
+ this._root = this.sections[ 0 ].root;
949
+ this.root = this.sections[ 1 ].root;
905
950
  }
906
951
 
907
952
  var type = options.type || "horizontal";
908
- var sizes = options.sizes || ["50%", "50%"];
953
+ var sizes = options.sizes || [ "50%", "50%" ];
909
954
  var infer_height = false;
910
- var auto = options.sizes === 'auto';
955
+ var auto = (options.sizes === 'auto');
911
956
 
912
- if( !sizes[1] )
957
+ if( !sizes[ 1 ] )
913
958
  {
914
- let size = sizes[0];
959
+ let size = sizes[ 0 ];
915
960
  let margin = options.top ? options.top : 0;
916
- if(size.constructor == Number) {
961
+ if( size.constructor == Number )
962
+ {
917
963
  size += margin;
918
964
  size += "px";
919
965
  }
920
966
 
921
- sizes[1] = "calc( 100% - " + size + " )";
967
+ sizes[ 1 ] = "calc( 100% - " + size + " )";
922
968
  infer_height = true;
923
969
  }
924
970
 
925
971
  // Create areas
926
- var area1 = new Area({ no_append: true, className: "split" + (options.menubar || options.sidebar ? "" : " origin") });
927
- var area2 = new Area({ no_append: true, className: "split"});
972
+ var area1 = new Area( { no_append: true, className: "split" + ( options.menubar || options.sidebar ? "" : " origin" ) } );
973
+ var area2 = new Area( { no_append: true, className: "split"} );
928
974
 
929
975
  area1.parentArea = this;
930
976
  area2.parentArea = this;
@@ -935,23 +981,27 @@ class Area {
935
981
  var data = "0px";
936
982
  this.offset = 0;
937
983
 
938
- if(resize)
984
+ if( resize )
939
985
  {
940
986
  this.resize = resize;
941
- this.split_bar = document.createElement("div");
987
+ this.split_bar = document.createElement( "div" );
942
988
  this.split_bar.className = "lexsplitbar " + type;
943
989
 
944
- if(type == "horizontal") {
990
+ if( type == "horizontal" )
991
+ {
945
992
  this.split_bar.style.width = LX.DEFAULT_SPLITBAR_SIZE + "px";
946
993
  }
947
- else {
994
+ else
995
+ {
948
996
  this.split_bar.style.height = LX.DEFAULT_SPLITBAR_SIZE + "px";
949
997
  }
950
- this.split_bar.addEventListener("mousedown", inner_mousedown);
951
- data = LX.DEFAULT_SPLITBAR_SIZE/2 + "px"; // updates
998
+
999
+ this.split_bar.addEventListener( 'mousedown', inner_mousedown );
1000
+
1001
+ data = ( LX.DEFAULT_SPLITBAR_SIZE / 2 ) + "px"; // updates
952
1002
 
953
1003
  // Being minimizable means it's also resizeable!
954
- if(minimizable)
1004
+ if( minimizable )
955
1005
  {
956
1006
  this.split_extended = false;
957
1007
 
@@ -973,14 +1023,14 @@ class Area {
973
1023
  }
974
1024
  }
975
1025
 
976
- if(type == "horizontal")
1026
+ if( type == "horizontal" )
977
1027
  {
978
- var width1 = sizes[0],
979
- width2 = sizes[1];
1028
+ var width1 = sizes[ 0 ],
1029
+ width2 = sizes[ 1 ];
980
1030
 
981
- if(width1.constructor == Number)
1031
+ if( width1.constructor == Number )
982
1032
  width1 += "px";
983
- if(width2.constructor == Number)
1033
+ if( width2.constructor == Number )
984
1034
  width2 += "px";
985
1035
 
986
1036
  area1.root.style.width = "calc( " + width1 + " - " + data + " )";
@@ -999,19 +1049,19 @@ class Area {
999
1049
  area1.root.style.height = "auto";
1000
1050
 
1001
1051
  // Listen resize event on first area
1002
- const resizeObserver = new ResizeObserver((entries) => {
1052
+ const resizeObserver = new ResizeObserver( entries => {
1003
1053
  for (const entry of entries) {
1004
1054
  const bb = entry.contentRect;
1005
1055
  area2.root.style.height = "calc(100% - " + ( bb.height + 4) + "px )";
1006
1056
  }
1007
1057
  });
1008
1058
 
1009
- resizeObserver.observe(area1.root);
1059
+ resizeObserver.observe( area1.root );
1010
1060
  }
1011
1061
  else
1012
1062
  {
1013
- var height1 = sizes[0],
1014
- height2 = sizes[1];
1063
+ var height1 = sizes[ 0 ],
1064
+ height2 = sizes[ 1 ];
1015
1065
 
1016
1066
  if(height1.constructor == Number)
1017
1067
  height1 += "px";
@@ -1026,7 +1076,7 @@ class Area {
1026
1076
 
1027
1077
  this.root.appendChild( area1.root );
1028
1078
 
1029
- if(resize)
1079
+ if( resize )
1030
1080
  {
1031
1081
  this.root.appendChild(this.split_bar);
1032
1082
  }
@@ -1038,55 +1088,67 @@ class Area {
1038
1088
  // Update sizes
1039
1089
  this._update();
1040
1090
 
1041
- if(!resize)
1091
+ if( !resize )
1042
1092
  {
1043
1093
  return this.sections;
1044
1094
  }
1045
1095
 
1046
- // from litegui.js @jagenjo
1047
-
1048
1096
  var that = this;
1049
- var last_pos = [0,0];
1050
- function inner_mousedown(e)
1097
+ var last_pos = [ 0, 0 ];
1098
+
1099
+ function inner_mousedown( e )
1051
1100
  {
1052
1101
  var doc = that.root.ownerDocument;
1053
- doc.addEventListener("mousemove",inner_mousemove);
1054
- doc.addEventListener("mouseup",inner_mouseup);
1102
+ doc.addEventListener( 'mousemove', inner_mousemove );
1103
+ doc.addEventListener( 'mouseup', inner_mouseup );
1055
1104
  last_pos[0] = e.x;
1056
1105
  last_pos[1] = e.y;
1057
1106
  e.stopPropagation();
1058
1107
  e.preventDefault();
1059
- document.body.classList.add("nocursor");
1060
- that.split_bar.classList.add("nocursor");
1108
+ document.body.classList.add( 'nocursor' );
1109
+ that.split_bar.classList.add( 'nocursor' );
1061
1110
  }
1062
1111
 
1063
- function inner_mousemove(e)
1112
+ function inner_mousemove( e )
1064
1113
  {
1065
- if(that.type == "horizontal") {
1066
- that._moveSplit(last_pos[0] - e.x);
1114
+ if(that.type == "horizontal")
1115
+ {
1116
+ that._moveSplit( last_pos[ 0 ] - e.x );
1067
1117
  }
1068
- else {
1069
- that._moveSplit(last_pos[1] - e.y);
1118
+ else
1119
+ {
1120
+ that._moveSplit( last_pos[ 1 ] - e.y );
1070
1121
  }
1071
1122
 
1072
- last_pos[0] = e.x;
1073
- last_pos[1] = e.y;
1123
+ last_pos[ 0 ] = e.x;
1124
+ last_pos[ 1 ] = e.y;
1125
+
1126
+ const widgets = that.root.querySelectorAll( ".lexwidget" );
1127
+
1128
+ // Send area resize to every widget in the area
1129
+ for( let widget of widgets )
1130
+ {
1131
+ const jsInstance = widget.jsIinstance;
1132
+
1133
+ if( jsInstance.onresize )
1134
+ {
1135
+ jsInstance.onresize();
1136
+ }
1137
+ }
1138
+
1074
1139
  e.stopPropagation();
1075
1140
  e.preventDefault();
1076
1141
  }
1077
1142
 
1078
- function inner_mouseup(e)
1143
+ function inner_mouseup( e )
1079
1144
  {
1080
1145
  var doc = that.root.ownerDocument;
1081
- doc.removeEventListener("mousemove",inner_mousemove);
1082
- doc.removeEventListener("mouseup",inner_mouseup);
1083
- document.body.classList.remove("nocursor");
1084
- that.split_bar.classList.remove("nocursor");
1146
+ doc.removeEventListener( 'mousemove', inner_mousemove );
1147
+ doc.removeEventListener( 'mouseup', inner_mouseup );
1148
+ document.body.classList.remove( 'nocursor' );
1149
+ that.split_bar.classList.remove( 'nocursor' );
1085
1150
  }
1086
1151
 
1087
- // Is this necessary?..
1088
- // setTimeout( () => this._moveSplit(0), 100);
1089
-
1090
1152
  return this.sections;
1091
1153
  }
1092
1154
 
@@ -1125,7 +1187,7 @@ class Area {
1125
1187
  this.propagateEvent("onresize");
1126
1188
  }
1127
1189
 
1128
- /**
1190
+ /**
1129
1191
  * @method extend
1130
1192
  * Hide 2nd area split
1131
1193
  */
@@ -1574,7 +1636,7 @@ class Tabs {
1574
1636
  this.classList.remove("dockingtab");
1575
1637
 
1576
1638
  // Change tabs instance
1577
- LX.emit( "@on_tab_docked", el.instance );
1639
+ LX.emit( "@on_tab_docked" );
1578
1640
  el.instance = that;
1579
1641
 
1580
1642
  // Show on drop
@@ -1646,22 +1708,26 @@ class Tabs {
1646
1708
 
1647
1709
  let isSelected = options.selected ?? false;
1648
1710
 
1649
- if( isSelected ) {
1650
- this.root.querySelectorAll('span').forEach( s => s.classList.remove('selected'));
1651
- this.area.root.querySelectorAll('.lextabcontent').forEach( c => c.style.display = 'none');
1711
+ if( isSelected )
1712
+ {
1713
+ this.root.querySelectorAll( 'span' ).forEach( s => s.classList.remove( 'selected' ) );
1714
+ this.area.root.querySelectorAll( '.lextabcontent' ).forEach( c => c.style.display = 'none' );
1652
1715
  }
1653
1716
 
1654
1717
  isSelected = !Object.keys( this.tabs ).length && !this.folding ? true : isSelected;
1655
1718
 
1656
1719
  let contentEl = content.root ? content.root : content;
1657
- contentEl.style.display = isSelected ? "block" : "none";
1658
- contentEl.classList.add("lextabcontent");
1720
+ contentEl.originalDisplay = contentEl.style.display;
1721
+ contentEl.style.display = isSelected ? contentEl.originalDisplay : "none";
1722
+ contentEl.classList.add( 'lextabcontent' );
1659
1723
 
1660
1724
  // Process icon
1661
1725
  if( options.icon )
1662
1726
  {
1663
1727
  if( options.icon.includes( 'fa-' ) ) // It's fontawesome icon...
1728
+ {
1664
1729
  options.icon = "<i class='" + options.icon + "'></i>";
1730
+ }
1665
1731
  else // an image..
1666
1732
  {
1667
1733
  const rootPath = "https://raw.githubusercontent.com/jxarco/lexgui.js/master/";
@@ -1670,26 +1736,31 @@ class Tabs {
1670
1736
  }
1671
1737
 
1672
1738
  // Create tab
1673
- let tabEl = document.createElement('span');
1674
- tabEl.dataset["name"] = name;
1675
- tabEl.className = "lexareatab" + (isSelected ? " selected" : "");
1676
- tabEl.innerHTML = (options.icon ?? "") + name;
1677
- tabEl.id = name.replace(/\s/g, '') + Tabs.TAB_ID++;
1739
+ let tabEl = document.createElement( 'span' );
1740
+ tabEl.dataset[ "name" ] = name;
1741
+ tabEl.className = "lexareatab" + ( isSelected ? " selected" : "" );
1742
+ tabEl.innerHTML = ( options.icon ?? "" ) + name;
1743
+ tabEl.id = name.replace( /\s/g, '' ) + Tabs.TAB_ID++;
1678
1744
  tabEl.title = options.title;
1679
1745
  tabEl.selected = isSelected ?? false;
1680
1746
  tabEl.fixed = options.fixed;
1681
- if(tabEl.selected)
1682
- this.selected = name;
1683
1747
  tabEl.instance = this;
1684
1748
  contentEl.id = tabEl.id + "_content";
1685
1749
 
1750
+ if( tabEl.selected )
1751
+ {
1752
+ this.selected = name;
1753
+ }
1754
+
1686
1755
  LX.addSignal( "@on_tab_docked", tabEl, function() {
1687
- if( this.parentElement.childNodes.length == 1 ){
1688
- this.parentElement.childNodes[0].click(); // single tab!!
1756
+ if( this.parentElement.childNodes.length == 1 )
1757
+ {
1758
+ this.parentElement.childNodes[ 0 ].click(); // single tab!!
1689
1759
  }
1690
1760
  } );
1691
1761
 
1692
1762
  tabEl.addEventListener("click", e => {
1763
+
1693
1764
  e.preventDefault();
1694
1765
  e.stopPropagation();
1695
1766
 
@@ -1697,25 +1768,27 @@ class Tabs {
1697
1768
  {
1698
1769
  // For folding tabs
1699
1770
  const lastValue = tabEl.selected;
1700
- tabEl.parentElement.querySelectorAll('span').forEach( s => s.selected = false );
1771
+ tabEl.parentElement.querySelectorAll( 'span' ).forEach( s => s.selected = false );
1701
1772
  tabEl.selected = !lastValue;
1702
1773
  // Manage selected
1703
- tabEl.parentElement.querySelectorAll('span').forEach( s => s.classList.remove('selected'));
1704
- tabEl.classList.toggle('selected', (this.folding && tabEl.selected));
1774
+ tabEl.parentElement.querySelectorAll( 'span' ).forEach( s => s.classList.remove( 'selected' ));
1775
+ tabEl.classList.toggle('selected', ( this.folding && tabEl.selected ));
1705
1776
  // Manage visibility
1706
- tabEl.instance.area.root.querySelectorAll('.lextabcontent').forEach( c => c.style.display = 'none');
1707
- contentEl.style.display = "block";
1777
+ tabEl.instance.area.root.querySelectorAll( '.lextabcontent' ).forEach( c => c.style.display = 'none' );
1778
+ contentEl.style.display = contentEl.originalDisplay;
1708
1779
  tabEl.instance.selected = tabEl.dataset.name;
1709
1780
  }
1710
1781
 
1711
1782
  if( this.folding )
1712
1783
  {
1713
1784
  this.folded = tabEl.selected;
1714
- this.area.root.classList.toggle('folded', !this.folded);
1785
+ this.area.root.classList.toggle( 'folded', !this.folded );
1715
1786
  }
1716
1787
 
1717
- if(options.onSelect)
1788
+ if( options.onSelect )
1789
+ {
1718
1790
  options.onSelect(e, tabEl.dataset.name);
1791
+ }
1719
1792
 
1720
1793
  if( this.thumb )
1721
1794
  {
@@ -1730,25 +1803,28 @@ class Tabs {
1730
1803
  e.preventDefault();
1731
1804
  e.stopPropagation();
1732
1805
 
1733
- if(options.onContextMenu)
1806
+ if( options.onContextMenu )
1807
+ {
1734
1808
  options.onContextMenu( e, tabEl.dataset.name );
1809
+ }
1735
1810
  });
1736
1811
 
1737
1812
  tabEl.addEventListener("mouseup", e => {
1738
1813
  e.preventDefault();
1739
1814
  e.stopPropagation();
1740
- if( e.button == 1 ) {
1741
- this.delete( tabEl.dataset["name"] );
1815
+ if( e.button == 1 )
1816
+ {
1817
+ this.delete( tabEl.dataset[ "name" ] );
1742
1818
  }
1743
1819
  });
1744
1820
 
1745
- tabEl.setAttribute('draggable', true);
1746
- tabEl.addEventListener("dragstart", function(e) {
1821
+ tabEl.setAttribute( 'draggable', true );
1822
+ tabEl.addEventListener( 'dragstart', function( e ) {
1747
1823
  if( this.parentElement.childNodes.length == 1 ){
1748
1824
  e.preventDefault();
1749
1825
  return;
1750
1826
  }
1751
- e.dataTransfer.setData( "source", e.target.id );
1827
+ e.dataTransfer.setData( 'source', e.target.id );
1752
1828
  });
1753
1829
 
1754
1830
  // Attach content
@@ -2394,7 +2470,7 @@ class Widget {
2394
2470
  console.warn("Can't get value of " + this.typeName());
2395
2471
  }
2396
2472
 
2397
- set( value, skipCallback = false ) {
2473
+ set( value, skipCallback = false, signalName = "" ) {
2398
2474
 
2399
2475
  if( this.onSetValue )
2400
2476
  return this.onSetValue( value, skipCallback );
@@ -2456,8 +2532,7 @@ class Widget {
2456
2532
  }
2457
2533
 
2458
2534
  refresh() {
2459
- // this.domEl.innerHTML = "";
2460
- // if( this.options.callback ) this.options.callback();
2535
+
2461
2536
  }
2462
2537
  }
2463
2538
 
@@ -3303,7 +3378,7 @@ class Panel {
3303
3378
 
3304
3379
  if( type != Widget.TITLE )
3305
3380
  {
3306
- element.style.width = "calc(100% - " + (this.current_branch || type == Widget.FILE || ( type == Widget.BUTTON && !name ) ? 10 : 20) + "px)";
3381
+ element.style.width = "calc(100% - " + (this.current_branch || type == Widget.FILE ? 10 : 20) + "px)";
3307
3382
  if( options.width ) {
3308
3383
  element.style.width = element.style.minWidth = options.width;
3309
3384
  }
@@ -3355,6 +3430,7 @@ class Panel {
3355
3430
  }
3356
3431
 
3357
3432
  widget.domEl = element;
3433
+ element.jsIinstance = widget;
3358
3434
 
3359
3435
  const insert_widget = el => {
3360
3436
  if(options.container)
@@ -3758,6 +3834,8 @@ class Panel {
3758
3834
  * placeholder: Add input placeholder
3759
3835
  * trigger: Choose onchange trigger (default, input) [default]
3760
3836
  * inputWidth: Width of the text input
3837
+ * float: Justify input text content
3838
+ * justifyName: Justify name content
3761
3839
  * fitHeight: Height adapts to text
3762
3840
  */
3763
3841
 
@@ -3795,6 +3873,7 @@ class Panel {
3795
3873
  let wValue = document.createElement( 'textarea' );
3796
3874
  wValue.value = wValue.iValue = value || "";
3797
3875
  wValue.style.width = "100%";
3876
+ wValue.style.textAlign = options.float ?? "";
3798
3877
  Object.assign( wValue.style, options.style ?? {} );
3799
3878
 
3800
3879
  if( options.disabled ?? false ) wValue.setAttribute("disabled", true);
@@ -3871,8 +3950,9 @@ class Panel {
3871
3950
  * @param {String} value Button name
3872
3951
  * @param {Function} callback Callback function on click
3873
3952
  * @param {*} options:
3874
- * icon
3875
3953
  * disabled: Make the widget disabled [false]
3954
+ * icon: Icon class to show as button value
3955
+ * img: Path to image to show as button value
3876
3956
  */
3877
3957
 
3878
3958
  addButton( name, value, callback, options = {} ) {
@@ -4380,10 +4460,14 @@ class Panel {
4380
4460
  element.appendChild( container );
4381
4461
 
4382
4462
  // Resize
4383
- curveInstance.canvas.width = container.offsetWidth;
4384
- curveInstance.redraw();
4385
4463
  widget.onresize = curveInstance.redraw.bind( curveInstance );
4386
4464
  widget.curveInstance = curveInstance;
4465
+
4466
+ doAsync(() => {
4467
+ curveInstance.canvas.width = container.offsetWidth;
4468
+ curveInstance.redraw();
4469
+ });
4470
+
4387
4471
  return widget;
4388
4472
  }
4389
4473
 
@@ -4487,6 +4571,7 @@ class Panel {
4487
4571
  * @param {Array} values By default values in the array
4488
4572
  * @param {Function} callback Callback function on change
4489
4573
  * @param {*} options:
4574
+ * innerValues (Array): Use dropdown mode and use values as options
4490
4575
  */
4491
4576
 
4492
4577
  addArray( name, values = [], callback, options = {} ) {
@@ -4936,7 +5021,7 @@ class Panel {
4936
5021
  container.style.width = "calc( 100% - " + LX.DEFAULT_NAME_WIDTH + ")";
4937
5022
 
4938
5023
  let color = document.createElement( 'input' );
4939
- color.style.width = "calc(30% - 6px)";
5024
+ color.style.width = "32px";
4940
5025
  color.type = 'color';
4941
5026
  color.className = "colorinput";
4942
5027
  color.id = "color" + simple_guidGenerator();
@@ -4977,7 +5062,7 @@ class Panel {
4977
5062
  change_from_input = true;
4978
5063
  widget.set( v );
4979
5064
  change_from_input = false;
4980
- }, { width: "calc(70% - 4px)" });
5065
+ }, { width: "calc( 100% - 32px )"});
4981
5066
 
4982
5067
  text_widget.domEl.style.marginLeft = "4px";
4983
5068
 
@@ -5408,9 +5493,9 @@ class Panel {
5408
5493
  * @param {*} options:
5409
5494
  * min, max: Min and Max values
5410
5495
  * low, optimum, high: Low and High boundary values, Optimum point in the range
5411
- * showValue: show current value
5412
- * editable: allow edit value
5413
- * callback: function called on change value
5496
+ * showValue: Show current value
5497
+ * editable: Allow edit value
5498
+ * callback: Function called on change value
5414
5499
  */
5415
5500
 
5416
5501
  addProgress( name, value, options = {} ) {
@@ -5669,64 +5754,93 @@ class Panel {
5669
5754
 
5670
5755
  /**
5671
5756
  * @method addTabs
5672
- * @param {Array} tabs Contains objects with {name, icon, callback}
5757
+ * @param {Array} tabs Contains objects with {
5758
+ * name: Name of the tab (if icon, use as title)
5759
+ * icon: Icon to be used as the tab icon (optional)
5760
+ * onCreate: Func to be called at tab creation
5761
+ * onSelect: Func to be called on select tab (optional)
5762
+ * }
5673
5763
  * @param {*} options
5674
5764
  * vertical: Use vertical or horizontal tabs (vertical by default)
5675
5765
  * showNames: Show tab name only in horizontal tabs
5676
5766
  */
5677
5767
 
5678
5768
  addTabs( tabs, options = {} ) {
5769
+
5679
5770
  let root = this.current_branch ? this.current_branch.content : this.root;
5680
- if(!this.current_branch)
5771
+
5772
+ if( !this.current_branch )
5773
+ {
5681
5774
  console.warn("No current branch!");
5775
+ }
5682
5776
 
5683
- if(tabs.constructor != Array)
5684
- throw("Param @tabs must be an Array!");
5777
+ if( tabs.constructor != Array )
5778
+ {
5779
+ throw( "Param @tabs must be an Array!" );
5780
+ }
5685
5781
 
5686
5782
  const vertical = options.vertical ?? true;
5687
- const showNames = !vertical && (options.showNames ?? false);
5783
+ const showNames = !vertical && ( options.showNames ?? false );
5688
5784
 
5689
- let container = document.createElement('div');
5785
+ let container = document.createElement( 'div' );
5690
5786
  container.className = "lextabscontainer";
5691
- if( !vertical ) container.className += " horizontal";
5787
+ if( !vertical )
5788
+ {
5789
+ container.className += " horizontal";
5790
+ }
5692
5791
 
5693
- let tabContainer = document.createElement("div");
5694
- tabContainer.className = "tabs";
5792
+ let tabContainer = document.createElement( 'div' );
5793
+ tabContainer.className = 'tabs';
5695
5794
  container.appendChild( tabContainer );
5696
5795
  root.appendChild( container );
5697
5796
 
5698
- for( var i = 0; i < tabs.length; ++i )
5797
+ for( let i = 0; i < tabs.length; ++i )
5699
5798
  {
5700
- const tab = tabs[i];
5701
- const selected = i == 0;
5702
- let tabEl = document.createElement('div');
5703
- tabEl.className = "lextab " + (i == tabs.length - 1 ? "last" : "") + (selected ? "selected" : "");
5704
- tabEl.innerHTML = (showNames ? tab.name : "") + "<a class='" + (tab.icon || "fa fa-hashtag") + " " + (showNames ? "withname" : "") + "'></a>";
5799
+ const tab = tabs[ i ];
5800
+ console.assert( tab.name );
5801
+ const isSelected = ( i == 0 );
5802
+ let tabEl = document.createElement( 'div' );
5803
+ tabEl.className = "lextab " + (i == tabs.length - 1 ? "last" : "") + ( isSelected ? "selected" : "" );
5804
+ tabEl.innerHTML = ( showNames ? tab.name : "" ) + "<a class='" + ( tab.icon || "fa fa-hashtag" ) + " " + (showNames ? "withname" : "") + "'></a>";
5705
5805
  tabEl.title = tab.name;
5706
5806
 
5707
- let infoContainer = document.createElement("div");
5708
- infoContainer.id = tab.name.replace(/\s/g, '');
5807
+ let infoContainer = document.createElement( 'div' );
5808
+ infoContainer.id = tab.name.replace( /\s/g, '' );
5709
5809
  infoContainer.className = "widgets";
5710
- if(!selected) infoContainer.toggleAttribute('hidden', true);
5810
+
5811
+ if(!isSelected)
5812
+ {
5813
+ infoContainer.toggleAttribute('hidden', true);
5814
+ }
5815
+
5711
5816
  container.appendChild( infoContainer );
5712
5817
 
5713
- tabEl.addEventListener("click", function() {
5714
- // change selected tab
5715
- tabContainer.querySelectorAll(".lextab").forEach( e => { e.classList.remove("selected"); } );
5716
- this.classList.add("selected");
5717
- // hide all tabs content
5718
- container.querySelectorAll(".widgets").forEach( e => { e.toggleAttribute('hidden', true); } );
5719
- // show tab content
5720
- const el = container.querySelector("#" + infoContainer.id);
5721
- el.toggleAttribute('hidden');
5818
+ tabEl.addEventListener( 'click', e => {
5819
+
5820
+ // Change selected tab
5821
+ tabContainer.querySelectorAll( '.lextab' ).forEach( e => { e.classList.remove( 'selected' ); } );
5822
+ e.target.classList.add( 'selected' );
5823
+ // Hide all tabs content
5824
+ container.querySelectorAll(".widgets").forEach( e => { e.toggleAttribute( 'hidden', true ); } );
5825
+ // Show tab content
5826
+ const el = container.querySelector( '#' + infoContainer.id );
5827
+ el.toggleAttribute( 'hidden' );
5828
+
5829
+ if( tab.onSelect )
5830
+ {
5831
+ tab.onSelect( this, infoContainer );
5832
+ }
5722
5833
  });
5723
5834
 
5724
- tabContainer.appendChild(tabEl);
5835
+ tabContainer.appendChild( tabEl );
5725
5836
 
5726
- // push to tab space
5727
- this.queue( infoContainer );
5728
- tab.callback( this, infoContainer );
5729
- this.clearQueue();
5837
+ if( tab.onCreate )
5838
+ {
5839
+ // push to tab space
5840
+ this.queue( infoContainer );
5841
+ tab.onCreate( this, infoContainer );
5842
+ this.clearQueue();
5843
+ }
5730
5844
  }
5731
5845
 
5732
5846
  this.addSeparator();
@@ -5742,14 +5856,19 @@ LX.Panel = Panel;
5742
5856
  class Branch {
5743
5857
 
5744
5858
  constructor( name, options = {} ) {
5859
+
5745
5860
  this.name = name;
5746
5861
 
5747
- var root = document.createElement('div');
5862
+ var root = document.createElement( 'div' );
5748
5863
  root.className = "lexbranch";
5749
- if(options.id)
5864
+ if( options.id )
5865
+ {
5750
5866
  root.id = options.id;
5751
- if(options.className)
5867
+ }
5868
+ if( options.className )
5869
+ {
5752
5870
  root.className += " " + options.className;
5871
+ }
5753
5872
 
5754
5873
  root.style.width = "calc(100% - 7px)";
5755
5874
  root.style.margin = "0 auto";
@@ -5760,52 +5879,56 @@ class Branch {
5760
5879
  this.widgets = [];
5761
5880
 
5762
5881
  // create element
5763
- var title = document.createElement('div');
5882
+ var title = document.createElement( 'div' );
5764
5883
  title.className = "lexbranchtitle";
5765
5884
 
5766
5885
  title.innerHTML = "<a class='fa-solid fa-angle-up switch-branch-button'></a>";
5767
- if(options.icon) {
5886
+ if( options.icon )
5887
+ {
5768
5888
  title.innerHTML += "<a class='branchicon " + options.icon + "' style='margin-right: 8px; margin-bottom: -2px;'>";
5769
5889
  }
5770
5890
  title.innerHTML += name || "Branch";
5771
5891
 
5772
- root.appendChild(title);
5892
+ root.appendChild( title );
5773
5893
 
5774
- var branch_content = document.createElement('div');
5775
- branch_content.id = name.replace(/\s/g, '');
5776
- branch_content.className = "lexbranchcontent";
5777
- root.appendChild(branch_content);
5778
- this.content = branch_content;
5894
+ var branchContent = document.createElement( 'div' );
5895
+ branchContent.id = name.replace(/\s/g, '');
5896
+ branchContent.className = "lexbranchcontent";
5897
+ root.appendChild(branchContent);
5898
+ this.content = branchContent;
5779
5899
 
5780
5900
  this._addBranchSeparator();
5781
5901
 
5782
- if( options.closed ) {
5902
+ if( options.closed )
5903
+ {
5783
5904
  title.className += " closed";
5784
5905
  root.className += " closed";
5785
5906
  this.grabber.setAttribute('hidden', true);
5786
5907
  doAsync( () => {
5787
- this.content.setAttribute('hidden', true);
5788
- }, 15);
5908
+ this.content.setAttribute( 'hidden', true );
5909
+ }, 15 );
5789
5910
  }
5790
5911
 
5791
- this.onclick = function(e){
5912
+ this.onclick = function( e ) {
5792
5913
  e.stopPropagation();
5793
- this.classList.toggle('closed');
5794
- this.parentElement.classList.toggle('closed');
5914
+ this.classList.toggle( 'closed' );
5915
+ this.parentElement.classList.toggle( 'closed' );
5795
5916
 
5796
- that.content.toggleAttribute('hidden');
5797
- that.grabber.toggleAttribute('hidden');
5917
+ that.content.toggleAttribute( 'hidden' );
5918
+ that.grabber.toggleAttribute( 'hidden' );
5798
5919
 
5799
- LX.emit("@on_branch_closed", this.classList.contains("closed"), that.panel);
5920
+ LX.emit( "@on_branch_closed", this.classList.contains("closed"), { target: that.panel } );
5800
5921
  };
5801
5922
 
5802
- this.oncontextmenu = function(e) {
5923
+ this.oncontextmenu = function( e ) {
5803
5924
 
5804
5925
  e.preventDefault();
5805
5926
  e.stopPropagation();
5806
5927
 
5807
5928
  if( this.parentElement.classList.contains("dialog") )
5929
+ {
5808
5930
  return;
5931
+ }
5809
5932
 
5810
5933
  addContextMenu("Dock", e, p => {
5811
5934
  e.preventDefault();
@@ -5813,12 +5936,12 @@ class Branch {
5813
5936
  // p.add('<i class="fa-regular fa-window-maximize fa-rotate-180">', {id: 'dock_options1'});
5814
5937
  // p.add('<i class="fa-regular fa-window-maximize fa-rotate-90">', {id: 'dock_options2'});
5815
5938
  // p.add('<i class="fa-regular fa-window-maximize fa-rotate-270">', {id: 'dock_options3'});
5816
- p.add('Floating', that._on_make_floating.bind(that));
5939
+ p.add( 'Floating', that._on_make_floating.bind( that ) );
5817
5940
  }, { icon: "fa-regular fa-window-restore" });
5818
5941
  };
5819
5942
 
5820
- title.addEventListener("click", this.onclick);
5821
- title.addEventListener("contextmenu", this.oncontextmenu);
5943
+ title.addEventListener( 'click', this.onclick );
5944
+ title.addEventListener( 'contextmenu', this.oncontextmenu );
5822
5945
  }
5823
5946
 
5824
5947
  _on_make_floating() {
@@ -6702,11 +6825,11 @@ class Curve {
6702
6825
 
6703
6826
  selected = computeSelected( mousex, canvas.height - mousey );
6704
6827
 
6705
- if(selected == -1 && element.allow_add_values) {
6706
- var v = unconvert([ mousex, canvas.height-mousey ]);
6707
- element.value.push(v);
6828
+ if( e.button == LX.MOUSE_LEFT_CLICK && selected == -1 && element.allow_add_values ) {
6829
+ var v = unconvert([ mousex, canvas.height - mousey ]);
6830
+ element.value.push( v );
6708
6831
  sortValues();
6709
- selected = element.value.indexOf(v);
6832
+ selected = element.value.indexOf( v );
6710
6833
  }
6711
6834
 
6712
6835
  last_mouse = [ mousex, mousey ];
@@ -6738,7 +6861,7 @@ class Curve {
6738
6861
  {
6739
6862
  const d = [ currentMouseDiff[ 0 ] - mousex, currentMouseDiff[ 1 ] - mousey ];
6740
6863
  let value = element.value[ selected ];
6741
- value[ 0 ] = ( d[ 0 ] == 0.0 ) ? value[ 0 ] : ( d[ 0 ] < 0.0 ? element.xrange[ 1 ] : element.xrange[ 0 ] );
6864
+ value[ 0 ] = ( d[ 0 ] == 0.0 ) ? value[ 0 ] : ( d[ 0 ] < 0.0 ? element.xrange[ 0 ] : element.xrange[ 1 ] );
6742
6865
  value[ 1 ] = ( d[ 1 ] == 0.0 ) ? value[ 1 ] : ( d[ 1 ] < 0.0 ? element.yrange[ 1 ] : element.yrange[ 0 ] );
6743
6866
  }
6744
6867