lexgui 0.1.35 → 0.1.37

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.
package/build/lexgui.js CHANGED
@@ -12,7 +12,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
12
12
  */
13
13
 
14
14
  var LX = global.LX = {
15
- version: "0.1.35",
15
+ version: "0.1.37",
16
16
  ready: false,
17
17
  components: [], // specific pre-build components
18
18
  signals: {} // events and triggers
@@ -29,7 +29,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
29
29
  LX.CURVE_MOVEOUT_DELETE = 1;
30
30
 
31
31
  function clamp( num, min, max ) { return Math.min( Math.max( num, min ), max ); }
32
- function round( num, n ) { return +num.toFixed( n ); }
32
+ function round( number, precision ) { return +(( number ).toFixed( precision ?? 2 ).replace( /([0-9]+(\.[0-9]+[1-9])?)(\.?0+$)/, '$1' )); }
33
33
 
34
34
  function getSupportedDOMName( string )
35
35
  {
@@ -45,43 +45,43 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
45
45
 
46
46
  LX.has = has;
47
47
 
48
- function getExtension(s)
48
+ function getExtension( s )
49
49
  {
50
50
  return s.includes('.') ? s.split('.').pop() : null;
51
51
  }
52
-
52
+
53
53
  LX.getExtension = getExtension;
54
-
55
- function deepCopy(o)
54
+
55
+ function deepCopy( o )
56
56
  {
57
57
  return JSON.parse(JSON.stringify(o))
58
58
  }
59
59
 
60
60
  LX.deepCopy = deepCopy;
61
61
 
62
- function setThemeColor(color_name, color)
62
+ function setThemeColor( colorName, color )
63
63
  {
64
- var r = document.querySelector(':root');
65
- r.style.setProperty("--" + color_name, color);
64
+ var r = document.querySelector( ':root' );
65
+ r.style.setProperty( '--' + colorName, color );
66
66
  }
67
67
 
68
68
  LX.setThemeColor = setThemeColor;
69
-
70
- function getThemeColor(color_name)
69
+
70
+ function getThemeColor( colorName )
71
71
  {
72
- var r = getComputedStyle(document.querySelector(':root'));
73
- return r.getPropertyValue("--" + color_name);
72
+ var r = getComputedStyle( document.querySelector( ':root' ) );
73
+ return r.getPropertyValue( '--' + colorName );
74
74
  }
75
75
 
76
76
  LX.getThemeColor = getThemeColor;
77
77
 
78
- function getBase64Image(img) {
79
- var canvas = document.createElement("canvas");
78
+ function getBase64Image( img ) {
79
+ var canvas = document.createElement( 'canvas' );
80
80
  canvas.width = img.width;
81
81
  canvas.height = img.height;
82
- var ctx = canvas.getContext("2d");
83
- ctx.drawImage(img, 0, 0);
84
- return canvas.toDataURL("image/png");
82
+ var ctx = canvas.getContext( '2d' );
83
+ ctx.drawImage( img, 0, 0 );
84
+ return canvas.toDataURL( 'image/png' );
85
85
  }
86
86
 
87
87
  LX.getBase64Image = getBase64Image;
@@ -113,6 +113,8 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
113
113
  return (S4()+"-"+S4()+"-"+S4());
114
114
  }
115
115
 
116
+ LX.guidGenerator = simple_guidGenerator;
117
+
116
118
  // Timer that works everywhere (from litegraph.js)
117
119
  if (typeof performance != "undefined") {
118
120
  LX.getTime = performance.now.bind(performance);
@@ -133,22 +135,26 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
133
135
 
134
136
  function doAsync( fn, ms ) {
135
137
  if( ASYNC_ENABLED )
138
+ {
136
139
  setTimeout( fn, ms ?? 0 );
140
+ }
137
141
  else
142
+ {
138
143
  fn();
144
+ }
139
145
  }
140
146
 
141
147
  // Math classes
142
148
 
143
149
  class vec2 {
144
150
 
145
- constructor(x, y) {
151
+ constructor( x, y ) {
146
152
  this.x = x ?? 0;
147
- this.y = y ?? (x ?? 0);
153
+ this.y = y ?? ( x ?? 0 );
148
154
  }
149
155
 
150
- get xy() { return [ this.x, this.y]; }
151
- get yx() { return [ this.y, this.x]; }
156
+ get xy() { return [ this.x, this.y ]; }
157
+ get yx() { return [ this.y, this.x ]; }
152
158
 
153
159
  set ( x, y ) { this.x = x; this.y = y; }
154
160
  add ( v, v0 = new vec2() ) { v0.set( this.x + v.x, this.y + v.y ); return v0; }
@@ -156,6 +162,11 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
156
162
  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; }
157
163
  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; }
158
164
  abs ( v0 = new vec2() ) { v0.set( Math.abs( this.x ), Math.abs( this.y ) ); return v0; }
165
+ dot ( v ) { return this.x * v.x + this.y * v.y; }
166
+ len2 () { return this.dot( this ) }
167
+ len () { return Math.sqrt( this.len2() ); }
168
+ nrm ( v0 = new vec2() ) { v0.set( this.x, this.y ); return v0.mul( 1.0 / this.len(), v0 ); }
169
+ dst ( v ) { return v.sub( this ).len(); }
159
170
  };
160
171
 
161
172
  LX.vec2 = vec2;
@@ -295,11 +306,18 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
295
306
  else
296
307
  {
297
308
  for( let c of LX.components )
298
- if( LX[c].prototype.onKeyPressed )
309
+ {
310
+ if( !LX[c] || !LX[c].prototype.onKeyPressed )
311
+ {
312
+ continue;
313
+ }
314
+
315
+ const instances = LX.CodeEditor.getInstances();
316
+ for( let i of instances )
299
317
  {
300
- const instances = LX.CodeEditor.getInstances();
301
- for( let i of instances ) i.onKeyPressed( e );
318
+ i.onKeyPressed( e );
302
319
  }
320
+ }
303
321
  }
304
322
  });
305
323
 
@@ -625,6 +643,8 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
625
643
  }
626
644
  };
627
645
 
646
+ LX.IEvent = IEvent;
647
+
628
648
  class TreeEvent {
629
649
 
630
650
  static NONE = 0;
@@ -661,16 +681,22 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
661
681
 
662
682
  LX.TreeEvent = TreeEvent;
663
683
 
664
- function emit( signal_name, value, target )
684
+ function emit( signalName, value, options = {} )
665
685
  {
666
- const data = LX.signals[ signal_name ];
686
+ const data = LX.signals[ signalName ];
667
687
 
668
688
  if( !data )
669
689
  return;
670
690
 
691
+ const target = options.target;
692
+
671
693
  if( target )
672
694
  {
673
- if(target[signal_name]) target[signal_name].call(target, value);
695
+ if( target[ signalName ])
696
+ {
697
+ target[ signalName ].call( target, value );
698
+ }
699
+
674
700
  return;
675
701
  }
676
702
 
@@ -678,13 +704,16 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
678
704
  {
679
705
  if( obj.constructor === Widget )
680
706
  {
681
- obj.set( value );
707
+ obj.set( value, options.skipCallback ?? true );
682
708
 
683
- if(obj.options && obj.options.callback)
684
- obj.options.callback(value, data);
685
- }else
709
+ if( obj.options && obj.options.callback )
710
+ {
711
+ obj.options.callback( value, data );
712
+ }
713
+ }
714
+ else
686
715
  {
687
- obj[signal_name].call(obj, value);
716
+ obj[ signalName ].call( obj, value );
688
717
  }
689
718
  }
690
719
  }
@@ -723,13 +752,17 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
723
752
  */
724
753
 
725
754
  constructor( options = {} ) {
726
-
727
- var root = document.createElement('div');
755
+
756
+ var root = document.createElement( 'div' );
728
757
  root.className = "lexarea";
729
- if(options.id)
758
+ if( options.id )
759
+ {
730
760
  root.id = options.id;
731
- if(options.className)
761
+ }
762
+ if( options.className )
763
+ {
732
764
  root.className += " " + options.className;
765
+ }
733
766
 
734
767
  var width = options.width || "calc( 100% )";
735
768
  var height = options.height || "100%";
@@ -737,10 +770,14 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
737
770
  // This has default options..
738
771
  this.setLimitBox( options.minWidth, options.minHeight, options.maxWidth, options.maxHeight );
739
772
 
740
- if(width.constructor == Number)
773
+ if( width.constructor == Number )
774
+ {
741
775
  width += "px";
742
- if(height.constructor == Number)
776
+ }
777
+ if( height.constructor == Number )
778
+ {
743
779
  height += "px";
780
+ }
744
781
 
745
782
  root.style.width = width;
746
783
  root.style.height = height;
@@ -751,115 +788,136 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
751
788
  this.sections = [];
752
789
  this.panels = [];
753
790
 
754
- if(!options.no_append) {
791
+ if( !options.no_append )
792
+ {
755
793
  var lexroot = document.getElementById("lexroot");
756
794
  lexroot.appendChild( this.root );
757
795
  }
758
796
 
759
797
  let overlay = options.overlay;
760
798
 
761
- if(overlay)
799
+ if( overlay )
762
800
  {
763
801
  this.root.classList.add("overlay-" + overlay);
764
-
765
- if( options.draggable )
802
+
803
+ if( options.left )
804
+ {
805
+ this.root.style.left = options.left;
806
+ }
807
+ else if( options.right )
808
+ {
809
+ this.root.style.right = options.right;
810
+ }
811
+ else if( options.top )
812
+ {
813
+ this.root.style.top = options.top;
814
+ }
815
+ else if( options.bottom )
816
+ {
817
+ this.root.style.bottom = options.bottom;
818
+ }
819
+
820
+ const draggable = options.draggable ?? true;
821
+ if( draggable )
766
822
  makeDraggable( root );
767
823
 
768
824
  if( options.resizeable ) {
769
825
  root.classList.add("resizeable");
770
826
  }
771
827
 
772
- if(options.resize)
828
+ if( options.resize )
773
829
  {
774
830
  this.split_bar = document.createElement("div");
775
- let type = overlay == "left" || overlay == "right" ? "horizontal" : "vertical";
831
+ let type = (overlay == "left") || (overlay == "right") ? "horizontal" : "vertical";
776
832
  this.type = overlay;;
777
833
  this.split_bar.className = "lexsplitbar " + type;
778
- if(overlay == "right") {
834
+
835
+ if( overlay == "right" )
836
+ {
779
837
  this.split_bar.style.width = LX.DEFAULT_SPLITBAR_SIZE + "px";
780
- this.split_bar.style.left = -LX.DEFAULT_SPLITBAR_SIZE/2 + "px";
838
+ this.split_bar.style.left = -(LX.DEFAULT_SPLITBAR_SIZE / 2.0) + "px";
781
839
  }
782
- else if(overlay == "left") {
840
+ else if( overlay == "left" )
841
+ {
783
842
  let size = Math.min(document.body.clientWidth - LX.DEFAULT_SPLITBAR_SIZE, this.root.clientWidth);
784
843
  this.split_bar.style.width = LX.DEFAULT_SPLITBAR_SIZE + "px";
785
- this.split_bar.style.left = size + LX.DEFAULT_SPLITBAR_SIZE/2 + "px";
844
+ this.split_bar.style.left = size + (LX.DEFAULT_SPLITBAR_SIZE / 2.0) + "px";
786
845
  }
787
- else if (overlay == "top") {
846
+ else if( overlay == "top" )
847
+ {
788
848
  let size = Math.min(document.body.clientHeight - LX.DEFAULT_SPLITBAR_SIZE, this.root.clientHeight);
789
849
  this.split_bar.style.height = LX.DEFAULT_SPLITBAR_SIZE + "px";
790
- this.split_bar.style.top = size + LX.DEFAULT_SPLITBAR_SIZE/2 + "px";
850
+ this.split_bar.style.top = size + (LX.DEFAULT_SPLITBAR_SIZE / 2.0) + "px";
791
851
  }
792
- else if(overlay == "bottom") {
852
+ else if( overlay == "bottom" )
853
+ {
793
854
  this.split_bar.style.height = LX.DEFAULT_SPLITBAR_SIZE + "px";
794
- this.split_bar.style.top = -LX.DEFAULT_SPLITBAR_SIZE/2 + "px";
855
+ this.split_bar.style.top = -(LX.DEFAULT_SPLITBAR_SIZE / 2.0) + "px";
795
856
  }
796
857
 
797
858
  this.split_bar.addEventListener("mousedown", inner_mousedown);
798
- this.root.appendChild(this.split_bar);
859
+ this.root.appendChild( this.split_bar );
799
860
 
800
861
  var that = this;
801
- var last_pos = [0,0];
862
+ var last_pos = [ 0, 0 ];
802
863
 
803
- function inner_mousedown(e)
864
+ function inner_mousedown( e )
804
865
  {
805
866
  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;
867
+ doc.addEventListener( 'mousemove', inner_mousemove );
868
+ doc.addEventListener( 'mouseup', inner_mouseup );
869
+ last_pos[ 0 ] = e.x;
870
+ last_pos[ 1 ] = e.y;
810
871
  e.stopPropagation();
811
872
  e.preventDefault();
812
- document.body.classList.add("nocursor");
813
- that.split_bar.classList.add("nocursor");
873
+ document.body.classList.add( 'nocursor' );
874
+ that.split_bar.classList.add( 'nocursor' );
814
875
  }
815
876
 
816
- function inner_mousemove(e)
877
+ function inner_mousemove( e )
817
878
  {
818
- switch(that.type) {
879
+ switch( that.type ) {
819
880
  case "right":
820
- var dt = (last_pos[0] - e.x);
821
- var size = (that.root.offsetWidth + dt);
881
+ var dt = ( last_pos[ 0 ] - e.x );
882
+ var size = ( that.root.offsetWidth + dt );
822
883
  that.root.style.width = size + "px";
823
884
  break;
824
-
825
885
  case "left":
826
- var dt = (last_pos[0] - e.x);
886
+ var dt = ( last_pos[ 0 ] - e.x );
827
887
  var size = Math.min(document.body.clientWidth - LX.DEFAULT_SPLITBAR_SIZE, (that.root.offsetWidth - dt));
828
888
  that.root.style.width = size + "px";
829
889
  that.split_bar.style.left = size + LX.DEFAULT_SPLITBAR_SIZE/2 + "px";
830
890
  break;
831
-
832
891
  case "top":
833
- var dt = (last_pos[1] - e.y);
892
+ var dt = ( last_pos[ 1 ] - e.y );
834
893
  var size = Math.min(document.body.clientHeight - LX.DEFAULT_SPLITBAR_SIZE, (that.root.offsetHeight - dt));
835
894
  that.root.style.height = size + "px";
836
895
  that.split_bar.style.top = size + LX.DEFAULT_SPLITBAR_SIZE/2 + "px";
837
896
  break;
838
-
839
897
  case "bottom":
840
- var dt = (last_pos[1] - e.y);
841
- var size = (that.root.offsetHeight + dt);
898
+ var dt = ( last_pos[ 1 ] - e.y );
899
+ var size = ( that.root.offsetHeight + dt );
842
900
  that.root.style.height = size + "px";
843
901
  break;
844
902
  }
845
903
 
846
- last_pos[0] = e.x;
847
- last_pos[1] = e.y;
904
+ last_pos[ 0 ] = e.x;
905
+ last_pos[ 1 ] = e.y;
848
906
  e.stopPropagation();
849
907
  e.preventDefault();
850
908
 
851
909
  // Resize events
852
- if(that.onresize)
910
+ if( that.onresize )
853
911
  that.onresize( that.root.getBoundingClientRect() );
854
912
  }
855
913
 
856
- function inner_mouseup(e)
914
+ function inner_mouseup( e )
857
915
  {
858
916
  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");
917
+ doc.removeEventListener( 'mousemove', inner_mousemove );
918
+ doc.removeEventListener( 'mouseup', inner_mouseup );
919
+ document.body.classList.remove( 'nocursor' );
920
+ that.split_bar.classList.remove( 'nocursor' );
863
921
  }
864
922
  }
865
923
  }
@@ -1142,7 +1200,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
1142
1200
  this.propagateEvent("onresize");
1143
1201
  }
1144
1202
 
1145
- /**
1203
+ /**
1146
1204
  * @method extend
1147
1205
  * Hide 2nd area split
1148
1206
  */
@@ -1592,7 +1650,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
1592
1650
  this.classList.remove("dockingtab");
1593
1651
 
1594
1652
  // Change tabs instance
1595
- LX.emit( "@on_tab_docked", el.instance );
1653
+ LX.emit( "@on_tab_docked" );
1596
1654
  el.instance = that;
1597
1655
 
1598
1656
  // Show on drop
@@ -1664,22 +1722,26 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
1664
1722
 
1665
1723
  let isSelected = options.selected ?? false;
1666
1724
 
1667
- if( isSelected ) {
1668
- this.root.querySelectorAll('span').forEach( s => s.classList.remove('selected'));
1669
- this.area.root.querySelectorAll('.lextabcontent').forEach( c => c.style.display = 'none');
1725
+ if( isSelected )
1726
+ {
1727
+ this.root.querySelectorAll( 'span' ).forEach( s => s.classList.remove( 'selected' ) );
1728
+ this.area.root.querySelectorAll( '.lextabcontent' ).forEach( c => c.style.display = 'none' );
1670
1729
  }
1671
1730
 
1672
1731
  isSelected = !Object.keys( this.tabs ).length && !this.folding ? true : isSelected;
1673
1732
 
1674
1733
  let contentEl = content.root ? content.root : content;
1675
- contentEl.style.display = isSelected ? "block" : "none";
1676
- contentEl.classList.add("lextabcontent");
1734
+ contentEl.originalDisplay = contentEl.style.display;
1735
+ contentEl.style.display = isSelected ? contentEl.originalDisplay : "none";
1736
+ contentEl.classList.add( 'lextabcontent' );
1677
1737
 
1678
1738
  // Process icon
1679
1739
  if( options.icon )
1680
1740
  {
1681
1741
  if( options.icon.includes( 'fa-' ) ) // It's fontawesome icon...
1742
+ {
1682
1743
  options.icon = "<i class='" + options.icon + "'></i>";
1744
+ }
1683
1745
  else // an image..
1684
1746
  {
1685
1747
  const rootPath = "https://raw.githubusercontent.com/jxarco/lexgui.js/master/";
@@ -1688,26 +1750,31 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
1688
1750
  }
1689
1751
 
1690
1752
  // Create tab
1691
- let tabEl = document.createElement('span');
1692
- tabEl.dataset["name"] = name;
1693
- tabEl.className = "lexareatab" + (isSelected ? " selected" : "");
1694
- tabEl.innerHTML = (options.icon ?? "") + name;
1695
- tabEl.id = name.replace(/\s/g, '') + Tabs.TAB_ID++;
1753
+ let tabEl = document.createElement( 'span' );
1754
+ tabEl.dataset[ "name" ] = name;
1755
+ tabEl.className = "lexareatab" + ( isSelected ? " selected" : "" );
1756
+ tabEl.innerHTML = ( options.icon ?? "" ) + name;
1757
+ tabEl.id = name.replace( /\s/g, '' ) + Tabs.TAB_ID++;
1696
1758
  tabEl.title = options.title;
1697
1759
  tabEl.selected = isSelected ?? false;
1698
1760
  tabEl.fixed = options.fixed;
1699
- if(tabEl.selected)
1700
- this.selected = name;
1701
1761
  tabEl.instance = this;
1702
1762
  contentEl.id = tabEl.id + "_content";
1703
1763
 
1764
+ if( tabEl.selected )
1765
+ {
1766
+ this.selected = name;
1767
+ }
1768
+
1704
1769
  LX.addSignal( "@on_tab_docked", tabEl, function() {
1705
- if( this.parentElement.childNodes.length == 1 ){
1706
- this.parentElement.childNodes[0].click(); // single tab!!
1770
+ if( this.parentElement.childNodes.length == 1 )
1771
+ {
1772
+ this.parentElement.childNodes[ 0 ].click(); // single tab!!
1707
1773
  }
1708
1774
  } );
1709
1775
 
1710
1776
  tabEl.addEventListener("click", e => {
1777
+
1711
1778
  e.preventDefault();
1712
1779
  e.stopPropagation();
1713
1780
 
@@ -1715,25 +1782,27 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
1715
1782
  {
1716
1783
  // For folding tabs
1717
1784
  const lastValue = tabEl.selected;
1718
- tabEl.parentElement.querySelectorAll('span').forEach( s => s.selected = false );
1785
+ tabEl.parentElement.querySelectorAll( 'span' ).forEach( s => s.selected = false );
1719
1786
  tabEl.selected = !lastValue;
1720
1787
  // Manage selected
1721
- tabEl.parentElement.querySelectorAll('span').forEach( s => s.classList.remove('selected'));
1722
- tabEl.classList.toggle('selected', (this.folding && tabEl.selected));
1788
+ tabEl.parentElement.querySelectorAll( 'span' ).forEach( s => s.classList.remove( 'selected' ));
1789
+ tabEl.classList.toggle('selected', ( this.folding && tabEl.selected ));
1723
1790
  // Manage visibility
1724
- tabEl.instance.area.root.querySelectorAll('.lextabcontent').forEach( c => c.style.display = 'none');
1725
- contentEl.style.display = "block";
1791
+ tabEl.instance.area.root.querySelectorAll( '.lextabcontent' ).forEach( c => c.style.display = 'none' );
1792
+ contentEl.style.display = contentEl.originalDisplay;
1726
1793
  tabEl.instance.selected = tabEl.dataset.name;
1727
1794
  }
1728
1795
 
1729
1796
  if( this.folding )
1730
1797
  {
1731
1798
  this.folded = tabEl.selected;
1732
- this.area.root.classList.toggle('folded', !this.folded);
1799
+ this.area.root.classList.toggle( 'folded', !this.folded );
1733
1800
  }
1734
1801
 
1735
- if(options.onSelect)
1802
+ if( options.onSelect )
1803
+ {
1736
1804
  options.onSelect(e, tabEl.dataset.name);
1805
+ }
1737
1806
 
1738
1807
  if( this.thumb )
1739
1808
  {
@@ -1748,25 +1817,28 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
1748
1817
  e.preventDefault();
1749
1818
  e.stopPropagation();
1750
1819
 
1751
- if(options.onContextMenu)
1820
+ if( options.onContextMenu )
1821
+ {
1752
1822
  options.onContextMenu( e, tabEl.dataset.name );
1823
+ }
1753
1824
  });
1754
1825
 
1755
1826
  tabEl.addEventListener("mouseup", e => {
1756
1827
  e.preventDefault();
1757
1828
  e.stopPropagation();
1758
- if( e.button == 1 ) {
1759
- this.delete( tabEl.dataset["name"] );
1829
+ if( e.button == 1 )
1830
+ {
1831
+ this.delete( tabEl.dataset[ "name" ] );
1760
1832
  }
1761
1833
  });
1762
1834
 
1763
- tabEl.setAttribute('draggable', true);
1764
- tabEl.addEventListener("dragstart", function(e) {
1835
+ tabEl.setAttribute( 'draggable', true );
1836
+ tabEl.addEventListener( 'dragstart', function( e ) {
1765
1837
  if( this.parentElement.childNodes.length == 1 ){
1766
1838
  e.preventDefault();
1767
1839
  return;
1768
1840
  }
1769
- e.dataTransfer.setData( "source", e.target.id );
1841
+ e.dataTransfer.setData( 'source', e.target.id );
1770
1842
  });
1771
1843
 
1772
1844
  // Attach content
@@ -2390,6 +2462,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
2390
2462
  static CONTENT = 20;
2391
2463
  static CUSTOM = 21;
2392
2464
  static SEPARATOR = 22;
2465
+ static KNOB = 23;
2393
2466
 
2394
2467
  static NO_CONTEXT_TYPES = [
2395
2468
  Widget.BUTTON,
@@ -2398,7 +2471,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
2398
2471
  Widget.PROGRESS
2399
2472
  ];
2400
2473
 
2401
- constructor(name, type, options) {
2474
+ constructor( name, type, options ) {
2402
2475
  this.name = name;
2403
2476
  this.type = type;
2404
2477
  this.options = options;
@@ -2406,10 +2479,12 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
2406
2479
 
2407
2480
  value() {
2408
2481
 
2409
- if(this.onGetValue)
2482
+ if( this.onGetValue )
2483
+ {
2410
2484
  return this.onGetValue();
2485
+ }
2411
2486
 
2412
- console.warn("Can't get value of " + this.typeName());
2487
+ console.warn( "Can't get value of " + this.typeName() );
2413
2488
  }
2414
2489
 
2415
2490
  set( value, skipCallback = false ) {
@@ -2469,13 +2544,13 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
2469
2544
  case Widget.LIST: return "List";
2470
2545
  case Widget.TAGS: return "Tags";
2471
2546
  case Widget.CURVE: return "Curve";
2547
+ case Widget.KNOB: return "Knob";
2472
2548
  case Widget.CUSTOM: return this.customName;
2473
2549
  }
2474
2550
  }
2475
2551
 
2476
2552
  refresh() {
2477
- // this.domEl.innerHTML = "";
2478
- // if( this.options.callback ) this.options.callback();
2553
+
2479
2554
  }
2480
2555
  }
2481
2556
 
@@ -3704,6 +3779,8 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
3704
3779
  * placeholder: Add input placeholder
3705
3780
  * trigger: Choose onchange trigger (default, input) [default]
3706
3781
  * inputWidth: Width of the text input
3782
+ * float: Justify input text content
3783
+ * justifyName: Justify name content
3707
3784
  * fitHeight: Height adapts to text
3708
3785
  */
3709
3786
 
@@ -3741,6 +3818,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
3741
3818
  let wValue = document.createElement( 'textarea' );
3742
3819
  wValue.value = wValue.iValue = value || "";
3743
3820
  wValue.style.width = "100%";
3821
+ wValue.style.textAlign = options.float ?? "";
3744
3822
  Object.assign( wValue.style, options.style ?? {} );
3745
3823
 
3746
3824
  if( options.disabled ?? false ) wValue.setAttribute("disabled", true);
@@ -3817,8 +3895,9 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
3817
3895
  * @param {String} value Button name
3818
3896
  * @param {Function} callback Callback function on click
3819
3897
  * @param {*} options:
3820
- * icon
3821
3898
  * disabled: Make the widget disabled [false]
3899
+ * icon: Icon class to show as button value
3900
+ * img: Path to image to show as button value
3822
3901
  */
3823
3902
 
3824
3903
  addButton( name, value, callback, options = {} ) {
@@ -4434,6 +4513,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
4434
4513
  * @param {Array} values By default values in the array
4435
4514
  * @param {Function} callback Callback function on change
4436
4515
  * @param {*} options:
4516
+ * innerValues (Array): Use dropdown mode and use values as options
4437
4517
  */
4438
4518
 
4439
4519
  addArray( name, values = [], callback, options = {} ) {
@@ -4778,7 +4858,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
4778
4858
  flag.className = "checkbox " + (flag.value ? "on" : "");
4779
4859
  flag.id = "checkbox"+simple_guidGenerator();
4780
4860
  flag.innerHTML = "<a class='fa-solid fa-check' style='display: " + (flag.value ? "block" : "none") + "'></a>";
4781
-
4861
+
4782
4862
  if( options.disabled ) {
4783
4863
  flag.disabled = true;
4784
4864
  toggle.className += " disabled";
@@ -4946,6 +5026,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
4946
5026
  * precision: The number of digits to appear after the decimal point
4947
5027
  * min, max: Min and Max values for the input
4948
5028
  * skipSlider: If there are min and max values, skip the slider
5029
+ * units: Unit as string added to the end of the value
4949
5030
  */
4950
5031
 
4951
5032
  addNumber( name, value, callback, options = {} ) {
@@ -4956,7 +5037,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
4956
5037
  return +vecinput.value;
4957
5038
  };
4958
5039
  widget.onSetValue = ( newValue, skipCallback ) => {
4959
- vecinput.value = newValue;
5040
+ vecinput.value = round( newValue, options.precision );
4960
5041
  Panel._dispatch_event( vecinput, "change", skipCallback );
4961
5042
  };
4962
5043
 
@@ -4981,27 +5062,48 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
4981
5062
  box.className = "numberbox";
4982
5063
 
4983
5064
  let vecinput = document.createElement( 'input' );
5065
+ vecinput.id = "number_" + simple_guidGenerator();
4984
5066
  vecinput.className = "vecinput";
4985
5067
  vecinput.min = options.min ?? -1e24;
4986
5068
  vecinput.max = options.max ?? 1e24;
4987
5069
  vecinput.step = options.step ?? "any";
4988
5070
  vecinput.type = "number";
4989
- vecinput.id = "number_" + simple_guidGenerator();
4990
5071
 
4991
5072
  if( value.constructor == Number )
4992
5073
  {
4993
5074
  value = clamp( value, +vecinput.min, +vecinput.max );
4994
- value = options.precision ? round( value, options.precision ) : value;
5075
+ value = round( value, options.precision );
4995
5076
  }
4996
5077
 
4997
5078
  vecinput.value = vecinput.iValue = value;
4998
5079
  box.appendChild( vecinput );
4999
5080
 
5000
- let drag_icon = document.createElement( 'a' );
5001
- drag_icon.className = "fa-solid fa-arrows-up-down drag-icon hidden";
5002
- box.appendChild( drag_icon );
5081
+ let measureRealWidth = function( value, paddingPlusMargin = 8 ) {
5082
+ var i = document.createElement( "span" );
5083
+ i.className = "lexinputmeasure";
5084
+ i.innerHTML = value;
5085
+ document.body.appendChild( i );
5086
+ var rect = i.getBoundingClientRect();
5087
+ LX.UTILS.deleteElement( i );
5088
+ return rect.width + paddingPlusMargin;
5089
+ }
5003
5090
 
5004
- if( options.disabled ) {
5091
+ if( options.units )
5092
+ {
5093
+ let unitSpan = document.createElement( 'span' );
5094
+ unitSpan.className = "lexunit";
5095
+ unitSpan.innerText = options.units;
5096
+ unitSpan.style.left = measureRealWidth( vecinput.value ) + "px";
5097
+ vecinput.unitSpan = unitSpan;
5098
+ box.appendChild( unitSpan );
5099
+ }
5100
+
5101
+ let dragIcon = document.createElement( 'a' );
5102
+ dragIcon.className = "fa-solid fa-arrows-up-down drag-icon hidden";
5103
+ box.appendChild( dragIcon );
5104
+
5105
+ if( options.disabled )
5106
+ {
5005
5107
  vecinput.disabled = true;
5006
5108
  }
5007
5109
 
@@ -5016,7 +5118,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5016
5118
  slider.value = value;
5017
5119
  slider.addEventListener( "input", function( e ) {
5018
5120
  let new_value = +this.valueAsNumber;
5019
- vecinput.value = ( +new_value ).toFixed( 4 ).replace( /([0-9]+(\.[0-9]+[1-9])?)(\.?0+$)/, '$1' );
5121
+ vecinput.value = round( new_value, options.precision );
5020
5122
  Panel._dispatch_event( vecinput, "change" );
5021
5123
  }, false );
5022
5124
  box.appendChild( slider );
@@ -5032,7 +5134,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5032
5134
  if( e.shiftKey ) mult *= 10;
5033
5135
  else if( e.altKey ) mult *= 0.1;
5034
5136
  let new_value = ( +this.valueAsNumber - mult * ( e.deltaY > 0 ? 1 : -1 ) );
5035
- this.value = ( +new_value ).toFixed( 4 ).replace( /([0-9]+(\.[0-9]+[1-9])?)(\.?0+$)/, '$1' );
5137
+ this.value = round( new_value, options.precision );
5036
5138
  Panel._dispatch_event(vecinput, "change");
5037
5139
  }, { passive: false });
5038
5140
 
@@ -5045,12 +5147,20 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5045
5147
 
5046
5148
  let val = e.target.value = clamp( +e.target.valueAsNumber, +vecinput.min, +vecinput.max );
5047
5149
  val = options.precision ? round( val, options.precision ) : val;
5048
- // update slider!
5150
+
5151
+ // Update slider!
5049
5152
  if( box.querySelector( ".lexinputslider" ) )
5153
+ {
5050
5154
  box.querySelector( ".lexinputslider" ).value = val;
5155
+ }
5051
5156
 
5052
5157
  vecinput.value = val;
5053
5158
 
5159
+ if( options.units )
5160
+ {
5161
+ vecinput.unitSpan.style.left = measureRealWidth( vecinput.value ) + "px";
5162
+ }
5163
+
5054
5164
  // Reset button (default value)
5055
5165
  if( !skipCallback )
5056
5166
  {
@@ -5075,7 +5185,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5075
5185
  lastY = e.pageY;
5076
5186
  document.body.classList.add('nocursor');
5077
5187
  document.body.classList.add('noevents');
5078
- drag_icon.classList.remove('hidden');
5188
+ dragIcon.classList.remove('hidden');
5079
5189
  e.stopImmediatePropagation();
5080
5190
  e.stopPropagation();
5081
5191
  }
@@ -5087,8 +5197,8 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5087
5197
  if(e.shiftKey) mult *= 10;
5088
5198
  else if(e.altKey) mult *= 0.1;
5089
5199
  let new_value = (+vecinput.valueAsNumber + mult * dt);
5090
- vecinput.value = (+new_value).toFixed(4).replace(/([0-9]+(\.[0-9]+[1-9])?)(\.?0+$)/,'$1');
5091
- Panel._dispatch_event(vecinput, "change");
5200
+ vecinput.value = (+new_value).toFixed( 4 ).replace(/([0-9]+(\.[0-9]+[1-9])?)(\.?0+$)/,'$1');
5201
+ Panel._dispatch_event( vecinput, "change" );
5092
5202
  }
5093
5203
 
5094
5204
  lastY = e.pageY;
@@ -5102,7 +5212,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5102
5212
  doc.removeEventListener("mouseup",inner_mouseup);
5103
5213
  document.body.classList.remove('nocursor');
5104
5214
  document.body.classList.remove('noevents');
5105
- drag_icon.classList.add('hidden');
5215
+ dragIcon.classList.add('hidden');
5106
5216
  }
5107
5217
 
5108
5218
  container.appendChild(box);
@@ -5139,9 +5249,15 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5139
5249
  };
5140
5250
  widget.onSetValue = ( newValue, skipCallback ) => {
5141
5251
  const inputs = element.querySelectorAll( ".vecinput" );
5252
+ if( inputs.length == newValue.length )
5253
+ {
5254
+ console.error( "Input length does not match vector length." );
5255
+ return;
5256
+ }
5257
+
5142
5258
  for( var i = 0; i < inputs.length; ++i ) {
5143
5259
  let value = newValue[ i ];
5144
- inputs[ i ].value = value ?? 0;
5260
+ inputs[ i ].value = round( value, options.precision ) ?? 0;
5145
5261
  Panel._dispatch_event( inputs[ i ], "change", skipCallback );
5146
5262
  }
5147
5263
  };
@@ -5181,14 +5297,14 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5181
5297
  if( value[ i ].constructor == Number )
5182
5298
  {
5183
5299
  value[ i ] = clamp(value[ i ], +vecinput.min, +vecinput.max);
5184
- value[ i ] = options.precision ? round(value[ i ], options.precision) : value[ i ];
5300
+ value[ i ] = round( value[ i ], options.precision );
5185
5301
  }
5186
5302
 
5187
5303
  vecinput.value = vecinput.iValue = value[ i ];
5188
5304
 
5189
- let drag_icon = document.createElement( 'a' );
5190
- drag_icon.className = "fa-solid fa-arrows-up-down drag-icon hidden";
5191
- box.appendChild( drag_icon );
5305
+ let dragIcon = document.createElement( 'a' );
5306
+ dragIcon.className = "fa-solid fa-arrows-up-down drag-icon hidden";
5307
+ box.appendChild( dragIcon );
5192
5308
 
5193
5309
  if( options.disabled ) {
5194
5310
  vecinput.disabled = true;
@@ -5204,14 +5320,17 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5204
5320
  if( e.shiftKey ) mult = 10;
5205
5321
  else if( e.altKey ) mult = 0.1;
5206
5322
 
5207
- if( lock_icon.locked )
5323
+ if( locker.locked )
5208
5324
  {
5209
- for( let v of element.querySelectorAll(".vecinput") ) {
5210
- v.value = ( +v.valueAsNumber - mult * ( e.deltaY > 0 ? 1 : -1 ) ).toPrecision( 5 );
5325
+ for( let v of element.querySelectorAll(".vecinput") )
5326
+ {
5327
+ v.value = round( +v.valueAsNumber - mult * ( e.deltaY > 0 ? 1 : -1 ), options.precision );
5211
5328
  Panel._dispatch_event(v, "change");
5212
5329
  }
5213
- } else {
5214
- this.value = ( +this.valueAsNumber - mult * ( e.deltaY > 0 ? 1 : -1 ) ).toPrecision( 5 );
5330
+ }
5331
+ else
5332
+ {
5333
+ this.value = round( +this.valueAsNumber - mult * ( e.deltaY > 0 ? 1 : -1 ), options.precision );
5215
5334
  Panel._dispatch_event( vecinput, "change" );
5216
5335
  }
5217
5336
  }, { passive: false } );
@@ -5224,7 +5343,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5224
5343
  const skipCallback = e.detail;
5225
5344
 
5226
5345
  let val = e.target.value = clamp( e.target.value, +vecinput.min, +vecinput.max );
5227
- val = options.precision ? round( val, options.precision ) : val;
5346
+ val = round( val, options.precision );
5228
5347
 
5229
5348
  // Reset button (default value)
5230
5349
  if( !skipCallback )
@@ -5233,7 +5352,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5233
5352
  if( btn ) btn.style.display = val != vecinput.iValue ? "block": "none";
5234
5353
  }
5235
5354
 
5236
- if( lock_icon.locked )
5355
+ if( locker.locked )
5237
5356
  {
5238
5357
  for( let v of element.querySelectorAll( ".vecinput" ) ) {
5239
5358
  v.value = val;
@@ -5261,7 +5380,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5261
5380
  lastY = e.pageY;
5262
5381
  document.body.classList.add('nocursor');
5263
5382
  document.body.classList.add('noevents');
5264
- drag_icon.classList.remove('hidden');
5383
+ dragIcon.classList.remove('hidden');
5265
5384
  e.stopImmediatePropagation();
5266
5385
  e.stopPropagation();
5267
5386
  }
@@ -5273,14 +5392,14 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5273
5392
  if(e.shiftKey) mult = 10;
5274
5393
  else if(e.altKey) mult = 0.1;
5275
5394
 
5276
- if( lock_icon.locked )
5395
+ if( locker.locked )
5277
5396
  {
5278
5397
  for( let v of element.querySelectorAll(".vecinput") ) {
5279
- v.value = (+v.valueAsNumber + mult * dt).toPrecision(5);
5398
+ v.value = round( +v.valueAsNumber + mult * dt, options.precision );
5280
5399
  Panel._dispatch_event(v, "change");
5281
5400
  }
5282
5401
  } else {
5283
- vecinput.value = (+vecinput.valueAsNumber + mult * dt).toPrecision(5);
5402
+ vecinput.value = round( +vecinput.valueAsNumber + mult * dt, options.precision );
5284
5403
  Panel._dispatch_event(vecinput, "change");
5285
5404
  }
5286
5405
  }
@@ -5290,23 +5409,23 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5290
5409
  e.preventDefault();
5291
5410
  }
5292
5411
 
5293
- function inner_mouseup(e) {
5412
+ function inner_mouseup( e ) {
5294
5413
  var doc = that.root.ownerDocument;
5295
5414
  doc.removeEventListener("mousemove",inner_mousemove);
5296
5415
  doc.removeEventListener("mouseup",inner_mouseup);
5297
5416
  document.body.classList.remove('nocursor');
5298
5417
  document.body.classList.remove('noevents');
5299
- drag_icon.classList.add('hidden');
5418
+ dragIcon.classList.add('hidden');
5300
5419
  }
5301
-
5302
- box.appendChild(vecinput);
5303
- container.appendChild(box);
5420
+
5421
+ box.appendChild( vecinput );
5422
+ container.appendChild( box );
5304
5423
  }
5305
5424
 
5306
- let lock_icon = document.createElement('a');
5307
- lock_icon.className = "fa-solid fa-lock-open lexicon";
5308
- container.appendChild(lock_icon);
5309
- lock_icon.addEventListener("click", function(e) {
5425
+ let locker = document.createElement('a');
5426
+ locker.className = "fa-solid fa-lock-open lexicon";
5427
+ container.appendChild(locker);
5428
+ locker.addEventListener("click", function(e) {
5310
5429
  this.locked = !this.locked;
5311
5430
  if(this.locked){
5312
5431
  this.classList.add("fa-lock");
@@ -5317,7 +5436,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5317
5436
  }
5318
5437
  }, false);
5319
5438
 
5320
- element.appendChild(container);
5439
+ element.appendChild( container );
5321
5440
 
5322
5441
  return widget;
5323
5442
  }
@@ -5355,9 +5474,9 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5355
5474
  * @param {*} options:
5356
5475
  * min, max: Min and Max values
5357
5476
  * low, optimum, high: Low and High boundary values, Optimum point in the range
5358
- * showValue: show current value
5359
- * editable: allow edit value
5360
- * callback: function called on change value
5477
+ * showValue: Show current value
5478
+ * editable: Allow edit value
5479
+ * callback: Function called on change value
5361
5480
  */
5362
5481
 
5363
5482
  addProgress( name, value, options = {} ) {
@@ -5611,64 +5730,93 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5611
5730
 
5612
5731
  /**
5613
5732
  * @method addTabs
5614
- * @param {Array} tabs Contains objects with {name, icon, callback}
5733
+ * @param {Array} tabs Contains objects with {
5734
+ * name: Name of the tab (if icon, use as title)
5735
+ * icon: Icon to be used as the tab icon (optional)
5736
+ * onCreate: Func to be called at tab creation
5737
+ * onSelect: Func to be called on select tab (optional)
5738
+ * }
5615
5739
  * @param {*} options
5616
5740
  * vertical: Use vertical or horizontal tabs (vertical by default)
5617
5741
  * showNames: Show tab name only in horizontal tabs
5618
5742
  */
5619
5743
 
5620
5744
  addTabs( tabs, options = {} ) {
5745
+
5621
5746
  let root = this.current_branch ? this.current_branch.content : this.root;
5622
- if(!this.current_branch)
5747
+
5748
+ if( !this.current_branch )
5749
+ {
5623
5750
  console.warn("No current branch!");
5751
+ }
5624
5752
 
5625
- if(tabs.constructor != Array)
5626
- throw("Param @tabs must be an Array!");
5753
+ if( tabs.constructor != Array )
5754
+ {
5755
+ throw( "Param @tabs must be an Array!" );
5756
+ }
5627
5757
 
5628
5758
  const vertical = options.vertical ?? true;
5629
- const showNames = !vertical && (options.showNames ?? false);
5759
+ const showNames = !vertical && ( options.showNames ?? false );
5630
5760
 
5631
- let container = document.createElement('div');
5761
+ let container = document.createElement( 'div' );
5632
5762
  container.className = "lextabscontainer";
5633
- if( !vertical ) container.className += " horizontal";
5763
+ if( !vertical )
5764
+ {
5765
+ container.className += " horizontal";
5766
+ }
5634
5767
 
5635
- let tabContainer = document.createElement("div");
5636
- tabContainer.className = "tabs";
5768
+ let tabContainer = document.createElement( 'div' );
5769
+ tabContainer.className = 'tabs';
5637
5770
  container.appendChild( tabContainer );
5638
5771
  root.appendChild( container );
5639
5772
 
5640
- for( var i = 0; i < tabs.length; ++i )
5773
+ for( let i = 0; i < tabs.length; ++i )
5641
5774
  {
5642
- const tab = tabs[i];
5643
- const selected = i == 0;
5644
- let tabEl = document.createElement('div');
5645
- tabEl.className = "lextab " + (i == tabs.length - 1 ? "last" : "") + (selected ? "selected" : "");
5646
- tabEl.innerHTML = (showNames ? tab.name : "") + "<a class='" + (tab.icon || "fa fa-hashtag") + " " + (showNames ? "withname" : "") + "'></a>";
5775
+ const tab = tabs[ i ];
5776
+ console.assert( tab.name );
5777
+ const isSelected = ( i == 0 );
5778
+ let tabEl = document.createElement( 'div' );
5779
+ tabEl.className = "lextab " + (i == tabs.length - 1 ? "last" : "") + ( isSelected ? "selected" : "" );
5780
+ tabEl.innerHTML = ( showNames ? tab.name : "" ) + "<a class='" + ( tab.icon || "fa fa-hashtag" ) + " " + (showNames ? "withname" : "") + "'></a>";
5647
5781
  tabEl.title = tab.name;
5648
5782
 
5649
- let infoContainer = document.createElement("div");
5650
- infoContainer.id = tab.name.replace(/\s/g, '');
5783
+ let infoContainer = document.createElement( 'div' );
5784
+ infoContainer.id = tab.name.replace( /\s/g, '' );
5651
5785
  infoContainer.className = "widgets";
5652
- if(!selected) infoContainer.toggleAttribute('hidden', true);
5786
+
5787
+ if(!isSelected)
5788
+ {
5789
+ infoContainer.toggleAttribute('hidden', true);
5790
+ }
5791
+
5653
5792
  container.appendChild( infoContainer );
5654
5793
 
5655
- tabEl.addEventListener("click", function() {
5656
- // change selected tab
5657
- tabContainer.querySelectorAll(".lextab").forEach( e => { e.classList.remove("selected"); } );
5658
- this.classList.add("selected");
5659
- // hide all tabs content
5660
- container.querySelectorAll(".widgets").forEach( e => { e.toggleAttribute('hidden', true); } );
5661
- // show tab content
5662
- const el = container.querySelector("#" + infoContainer.id);
5663
- el.toggleAttribute('hidden');
5794
+ tabEl.addEventListener( 'click', e => {
5795
+
5796
+ // Change selected tab
5797
+ tabContainer.querySelectorAll( '.lextab' ).forEach( e => { e.classList.remove( 'selected' ); } );
5798
+ e.target.classList.add( 'selected' );
5799
+ // Hide all tabs content
5800
+ container.querySelectorAll(".widgets").forEach( e => { e.toggleAttribute( 'hidden', true ); } );
5801
+ // Show tab content
5802
+ const el = container.querySelector( '#' + infoContainer.id );
5803
+ el.toggleAttribute( 'hidden' );
5804
+
5805
+ if( tab.onSelect )
5806
+ {
5807
+ tab.onSelect( this, infoContainer );
5808
+ }
5664
5809
  });
5665
5810
 
5666
- tabContainer.appendChild(tabEl);
5811
+ tabContainer.appendChild( tabEl );
5667
5812
 
5668
- // push to tab space
5669
- this.queue( infoContainer );
5670
- tab.callback( this, infoContainer );
5671
- this.clearQueue();
5813
+ if( tab.onCreate )
5814
+ {
5815
+ // push to tab space
5816
+ this.queue( infoContainer );
5817
+ tab.onCreate( this, infoContainer );
5818
+ this.clearQueue();
5819
+ }
5672
5820
  }
5673
5821
 
5674
5822
  this.addSeparator();
@@ -5684,14 +5832,19 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5684
5832
  class Branch {
5685
5833
 
5686
5834
  constructor( name, options = {} ) {
5835
+
5687
5836
  this.name = name;
5688
5837
 
5689
- var root = document.createElement('div');
5838
+ var root = document.createElement( 'div' );
5690
5839
  root.className = "lexbranch";
5691
- if(options.id)
5840
+ if( options.id )
5841
+ {
5692
5842
  root.id = options.id;
5693
- if(options.className)
5843
+ }
5844
+ if( options.className )
5845
+ {
5694
5846
  root.className += " " + options.className;
5847
+ }
5695
5848
 
5696
5849
  root.style.width = "calc(100% - 7px)";
5697
5850
  root.style.margin = "0 auto";
@@ -5702,65 +5855,69 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5702
5855
  this.widgets = [];
5703
5856
 
5704
5857
  // create element
5705
- var title = document.createElement('div');
5858
+ var title = document.createElement( 'div' );
5706
5859
  title.className = "lexbranchtitle";
5707
-
5860
+
5708
5861
  title.innerHTML = "<a class='fa-solid fa-angle-up switch-branch-button'></a>";
5709
- if(options.icon) {
5862
+ if( options.icon )
5863
+ {
5710
5864
  title.innerHTML += "<a class='branchicon " + options.icon + "' style='margin-right: 8px; margin-bottom: -2px;'>";
5711
5865
  }
5712
5866
  title.innerHTML += name || "Branch";
5713
5867
 
5714
- root.appendChild(title);
5868
+ root.appendChild( title );
5715
5869
 
5716
- var branch_content = document.createElement('div');
5717
- branch_content.id = name.replace(/\s/g, '');
5718
- branch_content.className = "lexbranchcontent";
5719
- root.appendChild(branch_content);
5720
- this.content = branch_content;
5870
+ var branchContent = document.createElement( 'div' );
5871
+ branchContent.id = name.replace(/\s/g, '');
5872
+ branchContent.className = "lexbranchcontent";
5873
+ root.appendChild(branchContent);
5874
+ this.content = branchContent;
5721
5875
 
5722
5876
  this._addBranchSeparator();
5723
5877
 
5724
- if( options.closed ) {
5878
+ if( options.closed )
5879
+ {
5725
5880
  title.className += " closed";
5726
5881
  root.className += " closed";
5727
5882
  this.grabber.setAttribute('hidden', true);
5728
5883
  doAsync( () => {
5729
- this.content.setAttribute('hidden', true);
5730
- }, 15);
5884
+ this.content.setAttribute( 'hidden', true );
5885
+ }, 15 );
5731
5886
  }
5732
5887
 
5733
- this.onclick = function(e){
5888
+ this.onclick = function( e ) {
5734
5889
  e.stopPropagation();
5735
- this.classList.toggle('closed');
5736
- this.parentElement.classList.toggle('closed');
5890
+ this.classList.toggle( 'closed' );
5891
+ this.parentElement.classList.toggle( 'closed' );
5737
5892
 
5738
- that.content.toggleAttribute('hidden');
5739
- that.grabber.toggleAttribute('hidden');
5893
+ that.content.toggleAttribute( 'hidden' );
5894
+ that.grabber.toggleAttribute( 'hidden' );
5740
5895
 
5741
- LX.emit("@on_branch_closed", this.classList.contains("closed"), that.panel);
5896
+ LX.emit( "@on_branch_closed", this.classList.contains("closed"), { target: that.panel } );
5742
5897
  };
5743
5898
 
5744
- this.oncontextmenu = function(e) {
5899
+ this.oncontextmenu = function( e ) {
5745
5900
 
5746
5901
  e.preventDefault();
5747
5902
  e.stopPropagation();
5748
5903
 
5749
5904
  if( this.parentElement.classList.contains("dialog") )
5750
- return;
5751
-
5905
+ {
5906
+ return;
5907
+ }
5908
+
5752
5909
  addContextMenu("Dock", e, p => {
5753
5910
  e.preventDefault();
5754
5911
  // p.add('<i class="fa-regular fa-window-maximize">', {id: 'dock_options0'});
5755
5912
  // p.add('<i class="fa-regular fa-window-maximize fa-rotate-180">', {id: 'dock_options1'});
5756
5913
  // p.add('<i class="fa-regular fa-window-maximize fa-rotate-90">', {id: 'dock_options2'});
5757
5914
  // p.add('<i class="fa-regular fa-window-maximize fa-rotate-270">', {id: 'dock_options3'});
5758
- p.add('Floating', that._on_make_floating.bind(that));
5915
+ p.add( 'Floating', that._on_make_floating.bind( that ) );
5759
5916
  }, { icon: "fa-regular fa-window-restore" });
5760
5917
  };
5761
5918
 
5762
- title.addEventListener("click", this.onclick);
5763
- title.addEventListener("contextmenu", this.oncontextmenu);
5919
+ title.addEventListener( 'click', this.onclick );
5920
+ title.addEventListener( 'contextmenu', this.oncontextmenu );
5764
5921
  }
5765
5922
 
5766
5923
  _on_make_floating() {
@@ -6199,7 +6356,8 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
6199
6356
  this.items = [];
6200
6357
  this.colors = {};
6201
6358
 
6202
- if(title) {
6359
+ if( title )
6360
+ {
6203
6361
  const item = {};
6204
6362
  item[ title ] = [];
6205
6363
  item[ 'className' ] = "cmtitle";
@@ -6214,7 +6372,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
6214
6372
 
6215
6373
  if(!useAbsolute)
6216
6374
  {
6217
- let width = rect.width + 36; // this has paddings
6375
+ let width = rect.width;
6218
6376
  if(window.innerWidth - rect.right < 0)
6219
6377
  div.style.left = (window.innerWidth - width - margin) + "px";
6220
6378
 
@@ -6255,7 +6413,6 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
6255
6413
  contextmenu.style.marginTop = 3.5 - c.offsetHeight + "px";
6256
6414
 
6257
6415
  // Set final width
6258
- // contextmenu.style.width = contextmenu.offsetWidth + "px";
6259
6416
  this._adjust_position( contextmenu, 6, true );
6260
6417
  }
6261
6418
 
@@ -6329,7 +6486,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
6329
6486
  }
6330
6487
 
6331
6488
  onCreate() {
6332
- this._adjust_position( this.root, 6 );
6489
+ doAsync( () => this._adjust_position( this.root, 6 ) );
6333
6490
  }
6334
6491
 
6335
6492
  add( path, options = {} ) {
@@ -6434,10 +6591,12 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
6434
6591
  function addContextMenu( title, event, callback, options )
6435
6592
  {
6436
6593
  var menu = new ContextMenu( event, title, options );
6437
- LX.root.appendChild(menu.root);
6594
+ LX.root.appendChild( menu.root );
6438
6595
 
6439
- if(callback)
6596
+ if( callback )
6597
+ {
6440
6598
  callback( menu );
6599
+ }
6441
6600
 
6442
6601
  menu.onCreate();
6443
6602