lexgui 0.6.9 → 0.6.10

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
@@ -14,7 +14,7 @@ console.warn( 'Script _build/lexgui.js_ is depracated and will be removed soon.
14
14
  */
15
15
 
16
16
  const LX = {
17
- version: "0.6.9",
17
+ version: "0.6.10",
18
18
  ready: false,
19
19
  components: [], // Specific pre-build components
20
20
  signals: {}, // Events and triggers
@@ -318,7 +318,7 @@ function _createCommandbar( root )
318
318
 
319
319
  const _propagateAdd = ( item, filter, path, skipPropagation ) => {
320
320
 
321
- if( !item )
321
+ if( !item || ( item.constructor != Object ) )
322
322
  {
323
323
  return;
324
324
  }
@@ -1537,7 +1537,7 @@ class ColorPicker {
1537
1537
  copyButtonWidget.root.querySelector( "input[type='checkbox']" ).style.pointerEvents = "none";
1538
1538
 
1539
1539
  LX.doAsync( () => {
1540
- copyButtonWidget.root.swap( true );
1540
+ copyButtonWidget.swap( true );
1541
1541
  copyButtonWidget.root.querySelector( "input[type='checkbox']" ).style.pointerEvents = "auto";
1542
1542
  }, 3000 );
1543
1543
 
@@ -6020,6 +6020,176 @@ LX.drawSpline = drawSpline;
6020
6020
 
6021
6021
  // area.js @jxarco
6022
6022
 
6023
+ class AreaOverlayButtons {
6024
+
6025
+ /**
6026
+ * @constructor AreaOverlayButtons
6027
+ */
6028
+
6029
+ constructor( area, buttonsArray, options = {} ) {
6030
+
6031
+ this.area = area;
6032
+ this.options = options;
6033
+
6034
+ this.buttons = {};
6035
+
6036
+ this._buildButtons( buttonsArray, options );
6037
+ }
6038
+
6039
+ _buildButtons( buttonsArray, options ) {
6040
+
6041
+ options.className = "lexoverlaybuttons";
6042
+
6043
+ let overlayPanel = this.area.addPanel( options );
6044
+ let overlayGroup = null;
6045
+
6046
+ const container = document.createElement( "div" );
6047
+ container.className = "lexoverlaybuttonscontainer";
6048
+ container.appendChild( overlayPanel.root );
6049
+ this.area.attach( container );
6050
+
6051
+ const float = options.float;
6052
+ let floatClass = "";
6053
+
6054
+ if( float )
6055
+ {
6056
+ for( let i = 0; i < float.length; i++ )
6057
+ {
6058
+ const t = float[ i ];
6059
+ switch( t )
6060
+ {
6061
+ case 'h': break;
6062
+ case 'v': floatClass += " vertical"; break;
6063
+ case 't': break;
6064
+ case 'm': floatClass += " middle"; break;
6065
+ case 'b': floatClass += " bottom"; break;
6066
+ case 'l': break;
6067
+ case 'c': floatClass += " center"; break;
6068
+ case 'r': floatClass += " right"; break;
6069
+ }
6070
+ }
6071
+
6072
+ container.className += ` ${ floatClass }`;
6073
+ }
6074
+
6075
+ const _addButton = ( b, group, last ) => {
6076
+
6077
+ const _options = {
6078
+ width: "auto",
6079
+ selectable: b.selectable,
6080
+ selected: b.selected,
6081
+ icon: b.icon,
6082
+ img: b.img,
6083
+ className: b.class ?? "",
6084
+ title: b.name,
6085
+ overflowContainerX: overlayPanel.root,
6086
+ swap: b.swap
6087
+ };
6088
+
6089
+ if( group )
6090
+ {
6091
+ if( !overlayGroup )
6092
+ {
6093
+ overlayGroup = document.createElement('div');
6094
+ overlayGroup.className = "lexoverlaygroup";
6095
+ overlayPanel.queuedContainer = overlayGroup;
6096
+ }
6097
+
6098
+ _options.parent = overlayGroup;
6099
+ }
6100
+
6101
+ let callback = b.callback;
6102
+ let widget = null;
6103
+
6104
+ if( b.options )
6105
+ {
6106
+ widget = overlayPanel.addSelect( null, b.options, b.value ?? b.name, callback, _options );
6107
+ }
6108
+ else
6109
+ {
6110
+ widget = overlayPanel.addButton( null, b.name, function( value, event ) {
6111
+ if( b.selectable )
6112
+ {
6113
+ if( b.group )
6114
+ {
6115
+ let _prev = b.selected;
6116
+ b.group.forEach( sub => sub.selected = false );
6117
+ b.selected = !_prev;
6118
+ }
6119
+ else
6120
+ {
6121
+ b.selected = !b.selected;
6122
+ }
6123
+ }
6124
+
6125
+ if( callback )
6126
+ {
6127
+ callback( value, event, widget.root );
6128
+ }
6129
+
6130
+ }, _options );
6131
+ }
6132
+
6133
+ this.buttons[ b.name ] = widget;
6134
+
6135
+ // ends the group
6136
+ if( overlayGroup && last )
6137
+ {
6138
+ overlayPanel.root.appendChild( overlayGroup );
6139
+ overlayGroup = null;
6140
+ overlayPanel.clearQueue();
6141
+ }
6142
+ };
6143
+
6144
+ const _refreshPanel = function() {
6145
+
6146
+ overlayPanel.clear();
6147
+
6148
+ for( let b of buttonsArray )
6149
+ {
6150
+ if( b === null )
6151
+ {
6152
+ // Add a separator
6153
+ const separator = document.createElement("div");
6154
+ separator.className = "lexoverlayseparator" + floatClass;
6155
+ overlayPanel.root.appendChild( separator );
6156
+ continue;
6157
+ }
6158
+
6159
+ if( b.constructor === Array )
6160
+ {
6161
+ for( let i = 0; i < b.length; ++i )
6162
+ {
6163
+ let sub = b[ i ];
6164
+ sub.group = b;
6165
+ _addButton( sub, true, i == ( b.length - 1 ) );
6166
+ }
6167
+ }
6168
+ else
6169
+ {
6170
+ _addButton( b );
6171
+ }
6172
+ }
6173
+
6174
+ // Add floating info
6175
+ if( float )
6176
+ {
6177
+ var height = 0;
6178
+ overlayPanel.root.childNodes.forEach( c => { height += c.offsetHeight; } );
6179
+
6180
+ if( container.className.includes( "middle" ) )
6181
+ {
6182
+ container.style.top = "-moz-calc( 50% - " + (height * 0.5) + "px )";
6183
+ container.style.top = "-webkit-calc( 50% - " + (height * 0.5) + "px )";
6184
+ container.style.top = "calc( 50% - " + (height * 0.5) + "px )";
6185
+ }
6186
+ }
6187
+ };
6188
+
6189
+ _refreshPanel();
6190
+ }
6191
+ }
6192
+
6023
6193
  class Area {
6024
6194
 
6025
6195
  /**
@@ -6785,8 +6955,7 @@ class Area {
6785
6955
  // Add to last split section if area has been split
6786
6956
  if( this.sections.length )
6787
6957
  {
6788
- this.sections[ 1 ].addOverlayButtons( buttons, options );
6789
- return;
6958
+ return this.sections[ 1 ].addOverlayButtons( buttons, options );
6790
6959
  }
6791
6960
 
6792
6961
  console.assert( buttons.constructor == Array && buttons.length );
@@ -6794,152 +6963,10 @@ class Area {
6794
6963
  // Set area to relative to use local position
6795
6964
  this.root.style.position = "relative";
6796
6965
 
6797
- options.className = "lexoverlaybuttons";
6798
-
6799
- let overlayPanel = this.addPanel( options );
6800
- let overlayGroup = null;
6801
-
6802
- const container = document.createElement("div");
6803
- container.className = "lexoverlaybuttonscontainer";
6804
- container.appendChild( overlayPanel.root );
6805
- this.attach( container );
6806
-
6807
- const float = options.float;
6808
- let floatClass = "";
6809
-
6810
- if( float )
6811
- {
6812
- for( let i = 0; i < float.length; i++ )
6813
- {
6814
- const t = float[ i ];
6815
- switch( t )
6816
- {
6817
- case 'h': break;
6818
- case 'v': floatClass += " vertical"; break;
6819
- case 't': break;
6820
- case 'm': floatClass += " middle"; break;
6821
- case 'b': floatClass += " bottom"; break;
6822
- case 'l': break;
6823
- case 'c': floatClass += " center"; break;
6824
- case 'r': floatClass += " right"; break;
6825
- }
6826
- }
6827
-
6828
- container.className += ` ${ floatClass }`;
6829
- }
6830
-
6831
- const _addButton = function( b, group, last ) {
6832
-
6833
- const _options = {
6834
- width: "auto",
6835
- selectable: b.selectable,
6836
- selected: b.selected,
6837
- icon: b.icon,
6838
- img: b.img,
6839
- className: b.class ?? "",
6840
- title: b.name,
6841
- overflowContainerX: overlayPanel.root,
6842
- swap: b.swap
6843
- };
6844
-
6845
- if( group )
6846
- {
6847
- if( !overlayGroup )
6848
- {
6849
- overlayGroup = document.createElement('div');
6850
- overlayGroup.className = "lexoverlaygroup";
6851
- overlayPanel.queuedContainer = overlayGroup;
6852
- }
6853
-
6854
- _options.parent = overlayGroup;
6855
- }
6856
-
6857
- let callback = b.callback;
6858
-
6859
- if( b.options )
6860
- {
6861
- overlayPanel.addSelect( null, b.options, b.name, callback, _options );
6862
- }
6863
- else
6864
- {
6865
- const button = overlayPanel.addButton( null, b.name, function( value, event ) {
6866
- if( b.selectable )
6867
- {
6868
- if( b.group )
6869
- {
6870
- let _prev = b.selected;
6871
- b.group.forEach( sub => sub.selected = false );
6872
- b.selected = !_prev;
6873
- }
6874
- else
6875
- {
6876
- b.selected = !b.selected;
6877
- }
6878
- }
6879
-
6880
- if( callback )
6881
- {
6882
- callback( value, event, button.root );
6883
- }
6884
-
6885
- }, _options );
6886
- }
6887
-
6888
- // ends the group
6889
- if( overlayGroup && last )
6890
- {
6891
- overlayPanel.root.appendChild( overlayGroup );
6892
- overlayGroup = null;
6893
- overlayPanel.clearQueue();
6894
- }
6895
- };
6896
-
6897
- const _refreshPanel = function() {
6898
-
6899
- overlayPanel.clear();
6900
-
6901
- for( let b of buttons )
6902
- {
6903
- if( b === null )
6904
- {
6905
- // Add a separator
6906
- const separator = document.createElement("div");
6907
- separator.className = "lexoverlayseparator" + floatClass;
6908
- overlayPanel.root.appendChild( separator );
6909
- continue;
6910
- }
6911
-
6912
- if( b.constructor === Array )
6913
- {
6914
- for( let i = 0; i < b.length; ++i )
6915
- {
6916
- let sub = b[ i ];
6917
- sub.group = b;
6918
- _addButton(sub, true, i == ( b.length - 1 ));
6919
- }
6920
- }
6921
- else
6922
- {
6923
- _addButton( b );
6924
- }
6925
- }
6966
+ // Reset if already exists
6967
+ this.overlayButtons = new AreaOverlayButtons( this, buttons, options );
6926
6968
 
6927
- // Add floating info
6928
- if( float )
6929
- {
6930
- var height = 0;
6931
- overlayPanel.root.childNodes.forEach( c => { height += c.offsetHeight; } );
6932
-
6933
- if( container.className.includes( "middle" ) )
6934
- {
6935
- container.style.top = "-moz-calc( 50% - " + (height * 0.5) + "px )";
6936
- container.style.top = "-webkit-calc( 50% - " + (height * 0.5) + "px )";
6937
- container.style.top = "calc( 50% - " + (height * 0.5) + "px )";
6938
- }
6939
- }
6940
- };
6941
-
6942
- _refreshPanel();
6969
+ return this.overlayButtons;
6943
6970
  }
6944
6971
 
6945
6972
  /**
@@ -8462,14 +8489,15 @@ class Button extends Widget {
8462
8489
  super( Widget.BUTTON, name, null, options );
8463
8490
 
8464
8491
  this.onGetValue = () => {
8465
- return wValue.querySelector( "input" )?.checked;
8492
+ const swapInput = wValue.querySelector( "input" );
8493
+ return swapInput ? swapInput.checked : value
8466
8494
  };
8467
8495
 
8468
8496
  this.onSetValue = ( newValue, skipCallback, event ) => {
8469
8497
 
8470
8498
  if( ( options.swap ?? false ) )
8471
8499
  {
8472
- this.root.setState( newValue, skipCallback );
8500
+ this.setState( newValue, skipCallback );
8473
8501
  return;
8474
8502
  }
8475
8503
 
@@ -8499,6 +8527,30 @@ class Button extends Widget {
8499
8527
  wValue.style.width = `calc( 100% - ${ realNameWidth })`;
8500
8528
  };
8501
8529
 
8530
+ // In case of swap, set if a change has to be performed
8531
+ this.setState = function( v, skipCallback ) {
8532
+ const swapInput = wValue.querySelector( "input" );
8533
+
8534
+ if( swapInput )
8535
+ {
8536
+ swapInput.checked = v;
8537
+ }
8538
+ else if( options.selectable )
8539
+ {
8540
+ if( options.parent )
8541
+ {
8542
+ options.parent.querySelectorAll(".lexbutton.selected").forEach( b => { if( b == wValue ) return; b.classList.remove( "selected" ); } );
8543
+ }
8544
+
8545
+ wValue.classList.toggle( "selected", v );
8546
+ }
8547
+
8548
+ if( !skipCallback )
8549
+ {
8550
+ this._trigger( new LX.IEvent( name, swapInput ? swapInput.checked : ( options.selectable ? v : value ), null ), callback );
8551
+ }
8552
+ };
8553
+
8502
8554
  var wValue = document.createElement( 'button' );
8503
8555
  wValue.title = options.tooltip ? "" : ( options.title ?? "" );
8504
8556
  wValue.className = "lexbutton p-1 " + ( options.buttonClass ?? "" );
@@ -8518,7 +8570,7 @@ class Button extends Widget {
8518
8570
  }
8519
8571
  else if( options.icon )
8520
8572
  {
8521
- const icon = LX.makeIcon( options.icon );
8573
+ const icon = LX.makeIcon( options.icon, { iconClass: options.iconClass, svgClass: options.svgClass } );
8522
8574
  const iconPosition = options.iconPosition ?? "cover";
8523
8575
 
8524
8576
  // Default
@@ -8589,7 +8641,7 @@ class Button extends Widget {
8589
8641
  const swapIcon = LX.makeIcon( options.swap, { iconClass: "swap-on" } );
8590
8642
  wValue.appendChild( swapIcon );
8591
8643
 
8592
- this.root.swap = function( skipCallback ) {
8644
+ this.swap = function( skipCallback ) {
8593
8645
  const swapInput = wValue.querySelector( "input" );
8594
8646
  swapInput.checked = !swapInput.checked;
8595
8647
  if( !skipCallback )
@@ -8597,19 +8649,10 @@ class Button extends Widget {
8597
8649
  trigger.click();
8598
8650
  }
8599
8651
  };
8600
-
8601
- // Set if swap has to be performed
8602
- this.root.setState = function( v, skipCallback ) {
8603
- const swapInput = wValue.querySelector( "input" );
8604
- swapInput.checked = v;
8605
- if( !skipCallback )
8606
- {
8607
- trigger.click();
8608
- }
8609
- };
8610
8652
  }
8611
8653
 
8612
8654
  trigger.addEventListener( "click", e => {
8655
+ let isSelected;
8613
8656
  if( options.selectable )
8614
8657
  {
8615
8658
  if( options.parent )
@@ -8617,7 +8660,7 @@ class Button extends Widget {
8617
8660
  options.parent.querySelectorAll(".lexbutton.selected").forEach( b => { if( b == wValue ) return; b.classList.remove( "selected" ); } );
8618
8661
  }
8619
8662
 
8620
- wValue.classList.toggle('selected');
8663
+ isSelected = wValue.classList.toggle('selected');
8621
8664
  }
8622
8665
 
8623
8666
  if( options.fileInput )
@@ -8627,7 +8670,7 @@ class Button extends Widget {
8627
8670
  else
8628
8671
  {
8629
8672
  const swapInput = wValue.querySelector( "input" );
8630
- this._trigger( new LX.IEvent( name, swapInput?.checked ?? value, e ), callback );
8673
+ this._trigger( new LX.IEvent( name, swapInput?.checked ?? ( options.selectable ? isSelected : value ), e ), callback );
8631
8674
  }
8632
8675
  });
8633
8676
 
@@ -9033,6 +9076,7 @@ class Select extends Widget {
9033
9076
  }
9034
9077
 
9035
9078
  this.root.dataset["opened"] = ( !!suboptionsFunc );
9079
+ list.style.height = ""; // set auto height by default
9036
9080
 
9037
9081
  if( !skipCallback )
9038
9082
  {
@@ -9054,7 +9098,7 @@ class Select extends Widget {
9054
9098
  wValue.name = name;
9055
9099
  wValue.iValue = value;
9056
9100
 
9057
- if( options.overflowContainer )
9101
+ if( options.overflowContainer !== undefined )
9058
9102
  {
9059
9103
  options.overflowContainerX = options.overflowContainerY = options.overflowContainer;
9060
9104
  }
@@ -9067,7 +9111,7 @@ class Select extends Widget {
9067
9111
 
9068
9112
  // Manage vertical aspect
9069
9113
  {
9070
- const overflowContainer = options.overflowContainerY ?? parent.getParentArea();
9114
+ const overflowContainer = options.overflowContainerY !== undefined ? options.overflowContainerY : parent.getParentArea();
9071
9115
  const listHeight = parent.offsetHeight;
9072
9116
  let topPosition = rect.y;
9073
9117
 
@@ -9087,18 +9131,25 @@ class Select extends Widget {
9087
9131
  }
9088
9132
 
9089
9133
  parent.style.top = ( topPosition + selectRoot.offsetHeight ) + 'px';
9134
+ list.style.height = ""; // set auto height by default
9090
9135
 
9091
- const showAbove = ( topPosition + listHeight ) > maxY;
9092
- if( showAbove )
9136
+ const failBelow = ( topPosition + listHeight ) > maxY;
9137
+ const failAbove = ( topPosition - listHeight ) < 0;
9138
+ if( failBelow && !failAbove )
9093
9139
  {
9094
9140
  parent.style.top = ( topPosition - listHeight ) + 'px';
9095
9141
  parent.classList.add( "place-above" );
9096
9142
  }
9143
+ // If does not fit in any direction, put it below but limit height..
9144
+ else if( failBelow && failAbove )
9145
+ {
9146
+ list.style.height = `${ maxY - topPosition - 32 }px`; // 32px margin
9147
+ }
9097
9148
  }
9098
9149
 
9099
9150
  // Manage horizontal aspect
9100
9151
  {
9101
- const overflowContainer = options.overflowContainerX ?? parent.getParentArea();
9152
+ const overflowContainer = options.overflowContainerX !== undefined ? options.overflowContainerX : parent.getParentArea();
9102
9153
  const listWidth = parent.offsetWidth;
9103
9154
  let leftPosition = rect.x;
9104
9155
 
@@ -9526,10 +9577,12 @@ class Layers extends Widget {
9526
9577
  container.style.width = `calc( 100% - ${ realNameWidth })`;
9527
9578
  };
9528
9579
 
9529
- var container = document.createElement( "div" );
9580
+ const container = document.createElement( "div" );
9530
9581
  container.className = "lexlayers";
9531
9582
  this.root.appendChild( container );
9532
9583
 
9584
+ const maxBits = options.maxBits ?? 16;
9585
+
9533
9586
  this.setLayers = ( val ) => {
9534
9587
 
9535
9588
  container.innerHTML = "";
@@ -9538,19 +9591,19 @@ class Layers extends Widget {
9538
9591
  let nbits = binary.length;
9539
9592
 
9540
9593
  // fill zeros
9541
- for( let i = 0; i < ( 16 - nbits ); ++i )
9594
+ for( let i = 0; i < ( maxBits - nbits ); ++i )
9542
9595
  {
9543
9596
  binary = '0' + binary;
9544
9597
  }
9545
9598
 
9546
- for( let bit = 0; bit < 16; ++bit )
9599
+ for( let bit = 0; bit < maxBits; ++bit )
9547
9600
  {
9548
9601
  let layer = document.createElement( "div" );
9549
9602
  layer.className = "lexlayer";
9550
9603
 
9551
9604
  if( val != undefined )
9552
9605
  {
9553
- const valueBit = binary[ 16 - bit - 1 ];
9606
+ const valueBit = binary[ maxBits - bit - 1 ];
9554
9607
  if( valueBit != undefined && valueBit == '1' )
9555
9608
  {
9556
9609
  layer.classList.add( "selected" );
@@ -9558,7 +9611,7 @@ class Layers extends Widget {
9558
9611
  }
9559
9612
 
9560
9613
  layer.innerText = bit + 1;
9561
- layer.title = "Bit " + bit + ", value " + (1 << bit);
9614
+ layer.title = "Bit " + bit + ", value " + ( 1 << bit );
9562
9615
  container.appendChild( layer );
9563
9616
 
9564
9617
  layer.addEventListener( "click", e => {
@@ -10205,9 +10258,7 @@ class ColorInput extends Widget {
10205
10258
  colorModel: options.useRGB ? "RGB" : "Hex",
10206
10259
  useAlpha,
10207
10260
  onChange: ( color ) => {
10208
- this._fromColorPicker = true;
10209
10261
  this.set( color.hex );
10210
- delete this._fromColorPicker;
10211
10262
  }
10212
10263
  } );
10213
10264
 
@@ -10245,6 +10296,7 @@ class ColorInput extends Widget {
10245
10296
  this._skipTextUpdate = true;
10246
10297
  this.set( v );
10247
10298
  delete this._skipTextUpdate;
10299
+ this.picker.fromHexColor( v );
10248
10300
  }, { width: "calc( 100% - 24px )", disabled: options.disabled });
10249
10301
 
10250
10302
  textWidget.root.style.marginLeft = "6px";
@@ -11517,9 +11569,16 @@ class TabSections extends Widget {
11517
11569
  throw( "Param @tabs must be an Array!" );
11518
11570
  }
11519
11571
 
11572
+ if( !tabs.length )
11573
+ {
11574
+ throw( "Tab list cannot be empty!" );
11575
+ }
11576
+
11520
11577
  const vertical = options.vertical ?? true;
11521
11578
  const showNames = !vertical && ( options.showNames ?? false );
11522
11579
 
11580
+ this.tabDOMs = {};
11581
+
11523
11582
  let container = document.createElement( 'div' );
11524
11583
  container.className = "lextabscontainer";
11525
11584
  if( !vertical )
@@ -11532,25 +11591,25 @@ class TabSections extends Widget {
11532
11591
  container.appendChild( tabContainer );
11533
11592
  this.root.appendChild( container );
11534
11593
 
11535
- for( let i = 0; i < tabs.length; ++i )
11594
+ // Check at least 1 is selected
11595
+ if( tabs.findIndex( e => e.selected === true ) < 0 )
11596
+ {
11597
+ tabs[ 0 ].selected = true;
11598
+ }
11599
+
11600
+ for( let tab of tabs )
11536
11601
  {
11537
- const tab = tabs[ i ];
11538
11602
  console.assert( tab.name );
11539
- const isSelected = ( i == 0 );
11540
11603
  let tabEl = document.createElement( "div" );
11541
- tabEl.className = "lextab " + (i == tabs.length - 1 ? "last" : "") + ( isSelected ? "selected" : "" );
11604
+ tabEl.className = "lextab " + ( ( tab.selected ?? false ) ? "selected" : "" );
11542
11605
  tabEl.innerHTML = ( showNames ? tab.name : "" );
11543
11606
  tabEl.appendChild( LX.makeIcon( tab.icon ?? "Hash", { title: tab.name, iconClass: tab.iconClass, svgClass: tab.svgClass } ) );
11607
+ this.tabDOMs[ tab.name ] = tabEl;
11544
11608
 
11545
11609
  let infoContainer = document.createElement( "div" );
11546
11610
  infoContainer.id = tab.name.replace( /\s/g, '' );
11547
11611
  infoContainer.className = "widgets";
11548
-
11549
- if( !isSelected )
11550
- {
11551
- infoContainer.toggleAttribute( "hidden", true );
11552
- }
11553
-
11612
+ infoContainer.toggleAttribute( "hidden", !( tab.selected ?? false ) );
11554
11613
  container.appendChild( infoContainer );
11555
11614
 
11556
11615
  tabEl.addEventListener( "click", e => {
@@ -11580,6 +11639,20 @@ class TabSections extends Widget {
11580
11639
  creationPanel.clearQueue();
11581
11640
  }
11582
11641
  }
11642
+
11643
+ this.tabs = tabs;
11644
+ }
11645
+
11646
+ select( name ) {
11647
+
11648
+ const tabEl = this.tabDOMs[ name ];
11649
+
11650
+ if( !tabEl )
11651
+ {
11652
+ return;
11653
+ }
11654
+
11655
+ tabEl.click();
11583
11656
  }
11584
11657
  }
11585
11658
 
@@ -14031,46 +14104,43 @@ class Menubar {
14031
14104
  }
14032
14105
 
14033
14106
  let button = this.buttons[ name ];
14107
+ // If the button already exists, delete it
14108
+ // since only one button of this type can exist
14034
14109
  if( button )
14035
14110
  {
14036
- button.innerHTML = "";
14037
- button.appendChild( LX.makeIcon( icon, { svgClass: "xl" } ) );
14038
- return;
14111
+ delete this.buttons[ name ];
14112
+ LX.deleteElement( button.root );
14039
14113
  }
14040
14114
 
14041
14115
  // Otherwise, create it
14042
- button = document.createElement('div');
14043
- const disabled = options.disabled ?? false;
14044
- button.className = "lexmenubutton main" + (disabled ? " disabled" : "");
14045
- button.title = name;
14046
- button.appendChild( LX.makeIcon( icon, { svgClass: "xl" } ) );
14116
+ button = new LX.Button( name, null, callback, {
14117
+ title: name,
14118
+ buttonClass: "lexmenubutton main bg-none",
14119
+ disabled: options.disabled,
14120
+ icon,
14121
+ svgClass: "xl",
14122
+ hideName: true,
14123
+ swap: options.swap
14124
+ } );
14047
14125
 
14048
14126
  if( options.float == "right" )
14049
14127
  {
14050
- button.right = true;
14128
+ button.root.right = true;
14051
14129
  }
14052
14130
 
14053
14131
  if( this.root.lastChild && this.root.lastChild.right )
14054
14132
  {
14055
- this.root.lastChild.before( button );
14133
+ this.root.lastChild.before( button.root );
14056
14134
  }
14057
14135
  else if( options.float == "left" )
14058
14136
  {
14059
- this.root.prepend( button );
14137
+ this.root.prepend( button.root );
14060
14138
  }
14061
14139
  else
14062
14140
  {
14063
- this.root.appendChild( button );
14141
+ this.root.appendChild( button.root );
14064
14142
  }
14065
14143
 
14066
- const _b = button.querySelector('a');
14067
- _b.addEventListener("click", (e) => {
14068
- if( callback && !disabled )
14069
- {
14070
- callback.call( this, _b, e );
14071
- }
14072
- });
14073
-
14074
14144
  this.buttons[ name ] = button;
14075
14145
  }
14076
14146
 
@@ -14176,7 +14246,7 @@ class Menubar {
14176
14246
 
14177
14247
  if( title )
14178
14248
  {
14179
- this.buttons[ title ] = button.root;
14249
+ this.buttons[ title ] = button;
14180
14250
  }
14181
14251
  }
14182
14252
  }
@@ -14937,10 +15007,14 @@ class AssetView {
14937
15007
 
14938
15008
  if( options.rootPath )
14939
15009
  {
14940
- if(options.rootPath.constructor !== String)
14941
- console.warn("Asset Root Path must be a String (now is " + path.constructor.name + ")");
15010
+ if( options.rootPath.constructor !== String )
15011
+ {
15012
+ console.warn( `Asset Root Path must be a String (now is a ${ path.constructor.name })` );
15013
+ }
14942
15014
  else
15015
+ {
14943
15016
  this.rootPath = options.rootPath;
15017
+ }
14944
15018
  }
14945
15019
 
14946
15020
  let div = document.createElement('div');
@@ -15309,7 +15383,7 @@ class AssetView {
15309
15383
  this.content.className = (isContentLayout ? "lexassetscontent" : "lexassetscontent list");
15310
15384
  let that = this;
15311
15385
 
15312
- const add_item = function(item) {
15386
+ const _addItem = function(item) {
15313
15387
 
15314
15388
  const type = item.type.charAt( 0 ).toUpperCase() + item.type.slice( 1 );
15315
15389
  const extension = LX.getExtension( item.id );
@@ -15334,20 +15408,27 @@ class AssetView {
15334
15408
  return;
15335
15409
  }
15336
15410
 
15411
+ const dialog = itemEl.closest('dialog');
15337
15412
  const rect = itemEl.getBoundingClientRect();
15338
15413
  const targetRect = e.target.getBoundingClientRect();
15339
- const parentRect = desc.parentElement.getBoundingClientRect();
15340
15414
 
15341
- let localOffsetX = targetRect.x - parentRect.x - ( targetRect.x - rect.x );
15342
- let localOffsetY = targetRect.y - parentRect.y - ( targetRect.y - rect.y );
15415
+ let localOffsetX = rect.x + e.offsetX;
15416
+ let localOffsetY = rect.y + e.offsetY;
15417
+
15418
+ if( dialog )
15419
+ {
15420
+ const dialogRect = dialog.getBoundingClientRect();
15421
+ localOffsetX -= dialogRect.x;
15422
+ localOffsetY -= dialogRect.y;
15423
+ }
15343
15424
 
15344
15425
  if( e.target.classList.contains( "lexassettitle" ) )
15345
15426
  {
15346
15427
  localOffsetY += ( targetRect.y - rect.y );
15347
15428
  }
15348
15429
 
15349
- desc.style.left = (localOffsetX + e.offsetX + 12) + "px";
15350
- desc.style.top = (localOffsetY + e.offsetY) + "px";
15430
+ desc.style.left = ( localOffsetX ) + "px";
15431
+ desc.style.top = ( localOffsetY - 36 ) + "px";
15351
15432
  });
15352
15433
 
15353
15434
  itemEl.addEventListener("mouseenter", () => {
@@ -15545,7 +15626,7 @@ class AssetView {
15545
15626
  } });
15546
15627
  }else
15547
15628
  {
15548
- item.domEl = add_item( item );
15629
+ item.domEl = _addItem( item );
15549
15630
  }
15550
15631
  }
15551
15632