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.
@@ -1,4 +1,4 @@
1
- // This is a generated file. Do not edit.
1
+ // This is a generated file. Do not edit.
2
2
  // Lexgui.js @jxarco
3
3
 
4
4
  /**
@@ -7,7 +7,7 @@
7
7
  */
8
8
 
9
9
  const LX = {
10
- version: "0.6.9",
10
+ version: "0.6.10",
11
11
  ready: false,
12
12
  components: [], // Specific pre-build components
13
13
  signals: {}, // Events and triggers
@@ -311,7 +311,7 @@ function _createCommandbar( root )
311
311
 
312
312
  const _propagateAdd = ( item, filter, path, skipPropagation ) => {
313
313
 
314
- if( !item )
314
+ if( !item || ( item.constructor != Object ) )
315
315
  {
316
316
  return;
317
317
  }
@@ -1530,7 +1530,7 @@ class ColorPicker {
1530
1530
  copyButtonWidget.root.querySelector( "input[type='checkbox']" ).style.pointerEvents = "none";
1531
1531
 
1532
1532
  LX.doAsync( () => {
1533
- copyButtonWidget.root.swap( true );
1533
+ copyButtonWidget.swap( true );
1534
1534
  copyButtonWidget.root.querySelector( "input[type='checkbox']" ).style.pointerEvents = "auto";
1535
1535
  }, 3000 );
1536
1536
 
@@ -4113,8 +4113,8 @@ Element.prototype.ignore = function( eventName, callbackName ) {
4113
4113
  callbackName = callbackName ?? ( "_on" + eventName );
4114
4114
  const callback = this[ callbackName ];
4115
4115
  this.removeEventListener( eventName, callback );
4116
- };
4117
-
4116
+ };
4117
+
4118
4118
  // icons.js @jxarco
4119
4119
 
4120
4120
  const RAW_ICONS = {
@@ -4292,8 +4292,8 @@ LX.LucideIconAlias = {
4292
4292
  "RotateRight": "RotateCw",
4293
4293
  "RotateBack": "RotateCcw",
4294
4294
  "RotateLeft": "RotateCcw",
4295
- };
4296
-
4295
+ };
4296
+
4297
4297
  // utils.js @jxarco
4298
4298
 
4299
4299
  function clamp( num, min, max ) { return Math.min( Math.max( num, min ), max ); }
@@ -6009,10 +6009,180 @@ function drawSpline( ctx, pts, t )
6009
6009
  ctx.restore();
6010
6010
  }
6011
6011
 
6012
- LX.drawSpline = drawSpline;
6013
-
6012
+ LX.drawSpline = drawSpline;
6013
+
6014
6014
  // area.js @jxarco
6015
6015
 
6016
+ class AreaOverlayButtons {
6017
+
6018
+ /**
6019
+ * @constructor AreaOverlayButtons
6020
+ */
6021
+
6022
+ constructor( area, buttonsArray, options = {} ) {
6023
+
6024
+ this.area = area;
6025
+ this.options = options;
6026
+
6027
+ this.buttons = {};
6028
+
6029
+ this._buildButtons( buttonsArray, options );
6030
+ }
6031
+
6032
+ _buildButtons( buttonsArray, options ) {
6033
+
6034
+ options.className = "lexoverlaybuttons";
6035
+
6036
+ let overlayPanel = this.area.addPanel( options );
6037
+ let overlayGroup = null;
6038
+
6039
+ const container = document.createElement( "div" );
6040
+ container.className = "lexoverlaybuttonscontainer";
6041
+ container.appendChild( overlayPanel.root );
6042
+ this.area.attach( container );
6043
+
6044
+ const float = options.float;
6045
+ let floatClass = "";
6046
+
6047
+ if( float )
6048
+ {
6049
+ for( let i = 0; i < float.length; i++ )
6050
+ {
6051
+ const t = float[ i ];
6052
+ switch( t )
6053
+ {
6054
+ case 'h': break;
6055
+ case 'v': floatClass += " vertical"; break;
6056
+ case 't': break;
6057
+ case 'm': floatClass += " middle"; break;
6058
+ case 'b': floatClass += " bottom"; break;
6059
+ case 'l': break;
6060
+ case 'c': floatClass += " center"; break;
6061
+ case 'r': floatClass += " right"; break;
6062
+ }
6063
+ }
6064
+
6065
+ container.className += ` ${ floatClass }`;
6066
+ }
6067
+
6068
+ const _addButton = ( b, group, last ) => {
6069
+
6070
+ const _options = {
6071
+ width: "auto",
6072
+ selectable: b.selectable,
6073
+ selected: b.selected,
6074
+ icon: b.icon,
6075
+ img: b.img,
6076
+ className: b.class ?? "",
6077
+ title: b.name,
6078
+ overflowContainerX: overlayPanel.root,
6079
+ swap: b.swap
6080
+ };
6081
+
6082
+ if( group )
6083
+ {
6084
+ if( !overlayGroup )
6085
+ {
6086
+ overlayGroup = document.createElement('div');
6087
+ overlayGroup.className = "lexoverlaygroup";
6088
+ overlayPanel.queuedContainer = overlayGroup;
6089
+ }
6090
+
6091
+ _options.parent = overlayGroup;
6092
+ }
6093
+
6094
+ let callback = b.callback;
6095
+ let widget = null;
6096
+
6097
+ if( b.options )
6098
+ {
6099
+ widget = overlayPanel.addSelect( null, b.options, b.value ?? b.name, callback, _options );
6100
+ }
6101
+ else
6102
+ {
6103
+ widget = overlayPanel.addButton( null, b.name, function( value, event ) {
6104
+ if( b.selectable )
6105
+ {
6106
+ if( b.group )
6107
+ {
6108
+ let _prev = b.selected;
6109
+ b.group.forEach( sub => sub.selected = false );
6110
+ b.selected = !_prev;
6111
+ }
6112
+ else
6113
+ {
6114
+ b.selected = !b.selected;
6115
+ }
6116
+ }
6117
+
6118
+ if( callback )
6119
+ {
6120
+ callback( value, event, widget.root );
6121
+ }
6122
+
6123
+ }, _options );
6124
+ }
6125
+
6126
+ this.buttons[ b.name ] = widget;
6127
+
6128
+ // ends the group
6129
+ if( overlayGroup && last )
6130
+ {
6131
+ overlayPanel.root.appendChild( overlayGroup );
6132
+ overlayGroup = null;
6133
+ overlayPanel.clearQueue();
6134
+ }
6135
+ };
6136
+
6137
+ const _refreshPanel = function() {
6138
+
6139
+ overlayPanel.clear();
6140
+
6141
+ for( let b of buttonsArray )
6142
+ {
6143
+ if( b === null )
6144
+ {
6145
+ // Add a separator
6146
+ const separator = document.createElement("div");
6147
+ separator.className = "lexoverlayseparator" + floatClass;
6148
+ overlayPanel.root.appendChild( separator );
6149
+ continue;
6150
+ }
6151
+
6152
+ if( b.constructor === Array )
6153
+ {
6154
+ for( let i = 0; i < b.length; ++i )
6155
+ {
6156
+ let sub = b[ i ];
6157
+ sub.group = b;
6158
+ _addButton( sub, true, i == ( b.length - 1 ) );
6159
+ }
6160
+ }
6161
+ else
6162
+ {
6163
+ _addButton( b );
6164
+ }
6165
+ }
6166
+
6167
+ // Add floating info
6168
+ if( float )
6169
+ {
6170
+ var height = 0;
6171
+ overlayPanel.root.childNodes.forEach( c => { height += c.offsetHeight; } );
6172
+
6173
+ if( container.className.includes( "middle" ) )
6174
+ {
6175
+ container.style.top = "-moz-calc( 50% - " + (height * 0.5) + "px )";
6176
+ container.style.top = "-webkit-calc( 50% - " + (height * 0.5) + "px )";
6177
+ container.style.top = "calc( 50% - " + (height * 0.5) + "px )";
6178
+ }
6179
+ }
6180
+ };
6181
+
6182
+ _refreshPanel();
6183
+ }
6184
+ }
6185
+
6016
6186
  class Area {
6017
6187
 
6018
6188
  /**
@@ -6778,8 +6948,7 @@ class Area {
6778
6948
  // Add to last split section if area has been split
6779
6949
  if( this.sections.length )
6780
6950
  {
6781
- this.sections[ 1 ].addOverlayButtons( buttons, options );
6782
- return;
6951
+ return this.sections[ 1 ].addOverlayButtons( buttons, options );
6783
6952
  }
6784
6953
 
6785
6954
  console.assert( buttons.constructor == Array && buttons.length );
@@ -6787,152 +6956,10 @@ class Area {
6787
6956
  // Set area to relative to use local position
6788
6957
  this.root.style.position = "relative";
6789
6958
 
6790
- options.className = "lexoverlaybuttons";
6791
-
6792
- let overlayPanel = this.addPanel( options );
6793
- let overlayGroup = null;
6794
-
6795
- const container = document.createElement("div");
6796
- container.className = "lexoverlaybuttonscontainer";
6797
- container.appendChild( overlayPanel.root );
6798
- this.attach( container );
6799
-
6800
- const float = options.float;
6801
- let floatClass = "";
6802
-
6803
- if( float )
6804
- {
6805
- for( let i = 0; i < float.length; i++ )
6806
- {
6807
- const t = float[ i ];
6808
- switch( t )
6809
- {
6810
- case 'h': break;
6811
- case 'v': floatClass += " vertical"; break;
6812
- case 't': break;
6813
- case 'm': floatClass += " middle"; break;
6814
- case 'b': floatClass += " bottom"; break;
6815
- case 'l': break;
6816
- case 'c': floatClass += " center"; break;
6817
- case 'r': floatClass += " right"; break;
6818
- }
6819
- }
6820
-
6821
- container.className += ` ${ floatClass }`;
6822
- }
6823
-
6824
- const _addButton = function( b, group, last ) {
6959
+ // Reset if already exists
6960
+ this.overlayButtons = new AreaOverlayButtons( this, buttons, options );
6825
6961
 
6826
- const _options = {
6827
- width: "auto",
6828
- selectable: b.selectable,
6829
- selected: b.selected,
6830
- icon: b.icon,
6831
- img: b.img,
6832
- className: b.class ?? "",
6833
- title: b.name,
6834
- overflowContainerX: overlayPanel.root,
6835
- swap: b.swap
6836
- };
6837
-
6838
- if( group )
6839
- {
6840
- if( !overlayGroup )
6841
- {
6842
- overlayGroup = document.createElement('div');
6843
- overlayGroup.className = "lexoverlaygroup";
6844
- overlayPanel.queuedContainer = overlayGroup;
6845
- }
6846
-
6847
- _options.parent = overlayGroup;
6848
- }
6849
-
6850
- let callback = b.callback;
6851
-
6852
- if( b.options )
6853
- {
6854
- overlayPanel.addSelect( null, b.options, b.name, callback, _options );
6855
- }
6856
- else
6857
- {
6858
- const button = overlayPanel.addButton( null, b.name, function( value, event ) {
6859
- if( b.selectable )
6860
- {
6861
- if( b.group )
6862
- {
6863
- let _prev = b.selected;
6864
- b.group.forEach( sub => sub.selected = false );
6865
- b.selected = !_prev;
6866
- }
6867
- else
6868
- {
6869
- b.selected = !b.selected;
6870
- }
6871
- }
6872
-
6873
- if( callback )
6874
- {
6875
- callback( value, event, button.root );
6876
- }
6877
-
6878
- }, _options );
6879
- }
6880
-
6881
- // ends the group
6882
- if( overlayGroup && last )
6883
- {
6884
- overlayPanel.root.appendChild( overlayGroup );
6885
- overlayGroup = null;
6886
- overlayPanel.clearQueue();
6887
- }
6888
- };
6889
-
6890
- const _refreshPanel = function() {
6891
-
6892
- overlayPanel.clear();
6893
-
6894
- for( let b of buttons )
6895
- {
6896
- if( b === null )
6897
- {
6898
- // Add a separator
6899
- const separator = document.createElement("div");
6900
- separator.className = "lexoverlayseparator" + floatClass;
6901
- overlayPanel.root.appendChild( separator );
6902
- continue;
6903
- }
6904
-
6905
- if( b.constructor === Array )
6906
- {
6907
- for( let i = 0; i < b.length; ++i )
6908
- {
6909
- let sub = b[ i ];
6910
- sub.group = b;
6911
- _addButton(sub, true, i == ( b.length - 1 ));
6912
- }
6913
- }
6914
- else
6915
- {
6916
- _addButton( b );
6917
- }
6918
- }
6919
-
6920
- // Add floating info
6921
- if( float )
6922
- {
6923
- var height = 0;
6924
- overlayPanel.root.childNodes.forEach( c => { height += c.offsetHeight; } );
6925
-
6926
- if( container.className.includes( "middle" ) )
6927
- {
6928
- container.style.top = "-moz-calc( 50% - " + (height * 0.5) + "px )";
6929
- container.style.top = "-webkit-calc( 50% - " + (height * 0.5) + "px )";
6930
- container.style.top = "calc( 50% - " + (height * 0.5) + "px )";
6931
- }
6932
- }
6933
- };
6934
-
6935
- _refreshPanel();
6962
+ return this.overlayButtons;
6936
6963
  }
6937
6964
 
6938
6965
  /**
@@ -7077,8 +7104,8 @@ class Area {
7077
7104
  }
7078
7105
  }
7079
7106
  }
7080
- LX.Area = Area;
7081
-
7107
+ LX.Area = Area;
7108
+
7082
7109
  // widget.js @jxarco
7083
7110
 
7084
7111
  /**
@@ -8455,14 +8482,15 @@ class Button extends Widget {
8455
8482
  super( Widget.BUTTON, name, null, options );
8456
8483
 
8457
8484
  this.onGetValue = () => {
8458
- return wValue.querySelector( "input" )?.checked;
8485
+ const swapInput = wValue.querySelector( "input" );
8486
+ return swapInput ? swapInput.checked : value
8459
8487
  };
8460
8488
 
8461
8489
  this.onSetValue = ( newValue, skipCallback, event ) => {
8462
8490
 
8463
8491
  if( ( options.swap ?? false ) )
8464
8492
  {
8465
- this.root.setState( newValue, skipCallback );
8493
+ this.setState( newValue, skipCallback );
8466
8494
  return;
8467
8495
  }
8468
8496
 
@@ -8492,6 +8520,30 @@ class Button extends Widget {
8492
8520
  wValue.style.width = `calc( 100% - ${ realNameWidth })`;
8493
8521
  };
8494
8522
 
8523
+ // In case of swap, set if a change has to be performed
8524
+ this.setState = function( v, skipCallback ) {
8525
+ const swapInput = wValue.querySelector( "input" );
8526
+
8527
+ if( swapInput )
8528
+ {
8529
+ swapInput.checked = v;
8530
+ }
8531
+ else if( options.selectable )
8532
+ {
8533
+ if( options.parent )
8534
+ {
8535
+ options.parent.querySelectorAll(".lexbutton.selected").forEach( b => { if( b == wValue ) return; b.classList.remove( "selected" ); } );
8536
+ }
8537
+
8538
+ wValue.classList.toggle( "selected", v );
8539
+ }
8540
+
8541
+ if( !skipCallback )
8542
+ {
8543
+ this._trigger( new LX.IEvent( name, swapInput ? swapInput.checked : ( options.selectable ? v : value ), null ), callback );
8544
+ }
8545
+ };
8546
+
8495
8547
  var wValue = document.createElement( 'button' );
8496
8548
  wValue.title = options.tooltip ? "" : ( options.title ?? "" );
8497
8549
  wValue.className = "lexbutton p-1 " + ( options.buttonClass ?? "" );
@@ -8511,7 +8563,7 @@ class Button extends Widget {
8511
8563
  }
8512
8564
  else if( options.icon )
8513
8565
  {
8514
- const icon = LX.makeIcon( options.icon );
8566
+ const icon = LX.makeIcon( options.icon, { iconClass: options.iconClass, svgClass: options.svgClass } );
8515
8567
  const iconPosition = options.iconPosition ?? "cover";
8516
8568
 
8517
8569
  // Default
@@ -8582,7 +8634,7 @@ class Button extends Widget {
8582
8634
  const swapIcon = LX.makeIcon( options.swap, { iconClass: "swap-on" } );
8583
8635
  wValue.appendChild( swapIcon );
8584
8636
 
8585
- this.root.swap = function( skipCallback ) {
8637
+ this.swap = function( skipCallback ) {
8586
8638
  const swapInput = wValue.querySelector( "input" );
8587
8639
  swapInput.checked = !swapInput.checked;
8588
8640
  if( !skipCallback )
@@ -8590,19 +8642,10 @@ class Button extends Widget {
8590
8642
  trigger.click();
8591
8643
  }
8592
8644
  };
8593
-
8594
- // Set if swap has to be performed
8595
- this.root.setState = function( v, skipCallback ) {
8596
- const swapInput = wValue.querySelector( "input" );
8597
- swapInput.checked = v;
8598
- if( !skipCallback )
8599
- {
8600
- trigger.click();
8601
- }
8602
- };
8603
8645
  }
8604
8646
 
8605
8647
  trigger.addEventListener( "click", e => {
8648
+ let isSelected;
8606
8649
  if( options.selectable )
8607
8650
  {
8608
8651
  if( options.parent )
@@ -8610,7 +8653,7 @@ class Button extends Widget {
8610
8653
  options.parent.querySelectorAll(".lexbutton.selected").forEach( b => { if( b == wValue ) return; b.classList.remove( "selected" ); } );
8611
8654
  }
8612
8655
 
8613
- wValue.classList.toggle('selected');
8656
+ isSelected = wValue.classList.toggle('selected');
8614
8657
  }
8615
8658
 
8616
8659
  if( options.fileInput )
@@ -8620,7 +8663,7 @@ class Button extends Widget {
8620
8663
  else
8621
8664
  {
8622
8665
  const swapInput = wValue.querySelector( "input" );
8623
- this._trigger( new LX.IEvent( name, swapInput?.checked ?? value, e ), callback );
8666
+ this._trigger( new LX.IEvent( name, swapInput?.checked ?? ( options.selectable ? isSelected : value ), e ), callback );
8624
8667
  }
8625
8668
  });
8626
8669
 
@@ -9026,6 +9069,7 @@ class Select extends Widget {
9026
9069
  }
9027
9070
 
9028
9071
  this.root.dataset["opened"] = ( !!suboptionsFunc );
9072
+ list.style.height = ""; // set auto height by default
9029
9073
 
9030
9074
  if( !skipCallback )
9031
9075
  {
@@ -9047,7 +9091,7 @@ class Select extends Widget {
9047
9091
  wValue.name = name;
9048
9092
  wValue.iValue = value;
9049
9093
 
9050
- if( options.overflowContainer )
9094
+ if( options.overflowContainer !== undefined )
9051
9095
  {
9052
9096
  options.overflowContainerX = options.overflowContainerY = options.overflowContainer;
9053
9097
  }
@@ -9060,7 +9104,7 @@ class Select extends Widget {
9060
9104
 
9061
9105
  // Manage vertical aspect
9062
9106
  {
9063
- const overflowContainer = options.overflowContainerY ?? parent.getParentArea();
9107
+ const overflowContainer = options.overflowContainerY !== undefined ? options.overflowContainerY : parent.getParentArea();
9064
9108
  const listHeight = parent.offsetHeight;
9065
9109
  let topPosition = rect.y;
9066
9110
 
@@ -9080,18 +9124,25 @@ class Select extends Widget {
9080
9124
  }
9081
9125
 
9082
9126
  parent.style.top = ( topPosition + selectRoot.offsetHeight ) + 'px';
9127
+ list.style.height = ""; // set auto height by default
9083
9128
 
9084
- const showAbove = ( topPosition + listHeight ) > maxY;
9085
- if( showAbove )
9129
+ const failBelow = ( topPosition + listHeight ) > maxY;
9130
+ const failAbove = ( topPosition - listHeight ) < 0;
9131
+ if( failBelow && !failAbove )
9086
9132
  {
9087
9133
  parent.style.top = ( topPosition - listHeight ) + 'px';
9088
9134
  parent.classList.add( "place-above" );
9089
9135
  }
9136
+ // If does not fit in any direction, put it below but limit height..
9137
+ else if( failBelow && failAbove )
9138
+ {
9139
+ list.style.height = `${ maxY - topPosition - 32 }px`; // 32px margin
9140
+ }
9090
9141
  }
9091
9142
 
9092
9143
  // Manage horizontal aspect
9093
9144
  {
9094
- const overflowContainer = options.overflowContainerX ?? parent.getParentArea();
9145
+ const overflowContainer = options.overflowContainerX !== undefined ? options.overflowContainerX : parent.getParentArea();
9095
9146
  const listWidth = parent.offsetWidth;
9096
9147
  let leftPosition = rect.x;
9097
9148
 
@@ -9519,10 +9570,12 @@ class Layers extends Widget {
9519
9570
  container.style.width = `calc( 100% - ${ realNameWidth })`;
9520
9571
  };
9521
9572
 
9522
- var container = document.createElement( "div" );
9573
+ const container = document.createElement( "div" );
9523
9574
  container.className = "lexlayers";
9524
9575
  this.root.appendChild( container );
9525
9576
 
9577
+ const maxBits = options.maxBits ?? 16;
9578
+
9526
9579
  this.setLayers = ( val ) => {
9527
9580
 
9528
9581
  container.innerHTML = "";
@@ -9531,19 +9584,19 @@ class Layers extends Widget {
9531
9584
  let nbits = binary.length;
9532
9585
 
9533
9586
  // fill zeros
9534
- for( let i = 0; i < ( 16 - nbits ); ++i )
9587
+ for( let i = 0; i < ( maxBits - nbits ); ++i )
9535
9588
  {
9536
9589
  binary = '0' + binary;
9537
9590
  }
9538
9591
 
9539
- for( let bit = 0; bit < 16; ++bit )
9592
+ for( let bit = 0; bit < maxBits; ++bit )
9540
9593
  {
9541
9594
  let layer = document.createElement( "div" );
9542
9595
  layer.className = "lexlayer";
9543
9596
 
9544
9597
  if( val != undefined )
9545
9598
  {
9546
- const valueBit = binary[ 16 - bit - 1 ];
9599
+ const valueBit = binary[ maxBits - bit - 1 ];
9547
9600
  if( valueBit != undefined && valueBit == '1' )
9548
9601
  {
9549
9602
  layer.classList.add( "selected" );
@@ -9551,7 +9604,7 @@ class Layers extends Widget {
9551
9604
  }
9552
9605
 
9553
9606
  layer.innerText = bit + 1;
9554
- layer.title = "Bit " + bit + ", value " + (1 << bit);
9607
+ layer.title = "Bit " + bit + ", value " + ( 1 << bit );
9555
9608
  container.appendChild( layer );
9556
9609
 
9557
9610
  layer.addEventListener( "click", e => {
@@ -10198,9 +10251,7 @@ class ColorInput extends Widget {
10198
10251
  colorModel: options.useRGB ? "RGB" : "Hex",
10199
10252
  useAlpha,
10200
10253
  onChange: ( color ) => {
10201
- this._fromColorPicker = true;
10202
10254
  this.set( color.hex );
10203
- delete this._fromColorPicker;
10204
10255
  }
10205
10256
  } );
10206
10257
 
@@ -10238,6 +10289,7 @@ class ColorInput extends Widget {
10238
10289
  this._skipTextUpdate = true;
10239
10290
  this.set( v );
10240
10291
  delete this._skipTextUpdate;
10292
+ this.picker.fromHexColor( v );
10241
10293
  }, { width: "calc( 100% - 24px )", disabled: options.disabled });
10242
10294
 
10243
10295
  textWidget.root.style.marginLeft = "6px";
@@ -11510,9 +11562,16 @@ class TabSections extends Widget {
11510
11562
  throw( "Param @tabs must be an Array!" );
11511
11563
  }
11512
11564
 
11565
+ if( !tabs.length )
11566
+ {
11567
+ throw( "Tab list cannot be empty!" );
11568
+ }
11569
+
11513
11570
  const vertical = options.vertical ?? true;
11514
11571
  const showNames = !vertical && ( options.showNames ?? false );
11515
11572
 
11573
+ this.tabDOMs = {};
11574
+
11516
11575
  let container = document.createElement( 'div' );
11517
11576
  container.className = "lextabscontainer";
11518
11577
  if( !vertical )
@@ -11525,25 +11584,25 @@ class TabSections extends Widget {
11525
11584
  container.appendChild( tabContainer );
11526
11585
  this.root.appendChild( container );
11527
11586
 
11528
- for( let i = 0; i < tabs.length; ++i )
11587
+ // Check at least 1 is selected
11588
+ if( tabs.findIndex( e => e.selected === true ) < 0 )
11589
+ {
11590
+ tabs[ 0 ].selected = true;
11591
+ }
11592
+
11593
+ for( let tab of tabs )
11529
11594
  {
11530
- const tab = tabs[ i ];
11531
11595
  console.assert( tab.name );
11532
- const isSelected = ( i == 0 );
11533
11596
  let tabEl = document.createElement( "div" );
11534
- tabEl.className = "lextab " + (i == tabs.length - 1 ? "last" : "") + ( isSelected ? "selected" : "" );
11597
+ tabEl.className = "lextab " + ( ( tab.selected ?? false ) ? "selected" : "" );
11535
11598
  tabEl.innerHTML = ( showNames ? tab.name : "" );
11536
11599
  tabEl.appendChild( LX.makeIcon( tab.icon ?? "Hash", { title: tab.name, iconClass: tab.iconClass, svgClass: tab.svgClass } ) );
11600
+ this.tabDOMs[ tab.name ] = tabEl;
11537
11601
 
11538
11602
  let infoContainer = document.createElement( "div" );
11539
11603
  infoContainer.id = tab.name.replace( /\s/g, '' );
11540
11604
  infoContainer.className = "widgets";
11541
-
11542
- if( !isSelected )
11543
- {
11544
- infoContainer.toggleAttribute( "hidden", true );
11545
- }
11546
-
11605
+ infoContainer.toggleAttribute( "hidden", !( tab.selected ?? false ) );
11547
11606
  container.appendChild( infoContainer );
11548
11607
 
11549
11608
  tabEl.addEventListener( "click", e => {
@@ -11573,6 +11632,20 @@ class TabSections extends Widget {
11573
11632
  creationPanel.clearQueue();
11574
11633
  }
11575
11634
  }
11635
+
11636
+ this.tabs = tabs;
11637
+ }
11638
+
11639
+ select( name ) {
11640
+
11641
+ const tabEl = this.tabDOMs[ name ];
11642
+
11643
+ if( !tabEl )
11644
+ {
11645
+ return;
11646
+ }
11647
+
11648
+ tabEl.click();
11576
11649
  }
11577
11650
  }
11578
11651
 
@@ -12445,8 +12518,8 @@ class Map2D extends Widget {
12445
12518
  }
12446
12519
  }
12447
12520
 
12448
- LX.Map2D = Map2D;
12449
-
12521
+ LX.Map2D = Map2D;
12522
+
12450
12523
  // panel.js @jxarco
12451
12524
 
12452
12525
  /**
@@ -13631,8 +13704,8 @@ class Panel {
13631
13704
  }
13632
13705
  }
13633
13706
 
13634
- LX.Panel = Panel;
13635
-
13707
+ LX.Panel = Panel;
13708
+
13636
13709
  // branch.js @jxarco
13637
13710
 
13638
13711
  /**
@@ -13856,8 +13929,8 @@ class Branch {
13856
13929
  }
13857
13930
  }
13858
13931
  }
13859
- LX.Branch = Branch;
13860
-
13932
+ LX.Branch = Branch;
13933
+
13861
13934
  // menubar.js @jxarco
13862
13935
 
13863
13936
  /**
@@ -14024,46 +14097,43 @@ class Menubar {
14024
14097
  }
14025
14098
 
14026
14099
  let button = this.buttons[ name ];
14100
+ // If the button already exists, delete it
14101
+ // since only one button of this type can exist
14027
14102
  if( button )
14028
14103
  {
14029
- button.innerHTML = "";
14030
- button.appendChild( LX.makeIcon( icon, { svgClass: "xl" } ) );
14031
- return;
14104
+ delete this.buttons[ name ];
14105
+ LX.deleteElement( button.root );
14032
14106
  }
14033
14107
 
14034
14108
  // Otherwise, create it
14035
- button = document.createElement('div');
14036
- const disabled = options.disabled ?? false;
14037
- button.className = "lexmenubutton main" + (disabled ? " disabled" : "");
14038
- button.title = name;
14039
- button.appendChild( LX.makeIcon( icon, { svgClass: "xl" } ) );
14109
+ button = new LX.Button( name, null, callback, {
14110
+ title: name,
14111
+ buttonClass: "lexmenubutton main bg-none",
14112
+ disabled: options.disabled,
14113
+ icon,
14114
+ svgClass: "xl",
14115
+ hideName: true,
14116
+ swap: options.swap
14117
+ } );
14040
14118
 
14041
14119
  if( options.float == "right" )
14042
14120
  {
14043
- button.right = true;
14121
+ button.root.right = true;
14044
14122
  }
14045
14123
 
14046
14124
  if( this.root.lastChild && this.root.lastChild.right )
14047
14125
  {
14048
- this.root.lastChild.before( button );
14126
+ this.root.lastChild.before( button.root );
14049
14127
  }
14050
14128
  else if( options.float == "left" )
14051
14129
  {
14052
- this.root.prepend( button );
14130
+ this.root.prepend( button.root );
14053
14131
  }
14054
14132
  else
14055
14133
  {
14056
- this.root.appendChild( button );
14134
+ this.root.appendChild( button.root );
14057
14135
  }
14058
14136
 
14059
- const _b = button.querySelector('a');
14060
- _b.addEventListener("click", (e) => {
14061
- if( callback && !disabled )
14062
- {
14063
- callback.call( this, _b, e );
14064
- }
14065
- });
14066
-
14067
14137
  this.buttons[ name ] = button;
14068
14138
  }
14069
14139
 
@@ -14169,13 +14239,13 @@ class Menubar {
14169
14239
 
14170
14240
  if( title )
14171
14241
  {
14172
- this.buttons[ title ] = button.root;
14242
+ this.buttons[ title ] = button;
14173
14243
  }
14174
14244
  }
14175
14245
  }
14176
14246
  }
14177
- LX.Menubar = Menubar;
14178
-
14247
+ LX.Menubar = Menubar;
14248
+
14179
14249
  // sidebar.js @jxarco
14180
14250
 
14181
14251
  /**
@@ -14870,8 +14940,8 @@ class Sidebar {
14870
14940
  }
14871
14941
  }
14872
14942
  }
14873
- LX.Sidebar = Sidebar;
14874
-
14943
+ LX.Sidebar = Sidebar;
14944
+
14875
14945
  // asset_view.js @jxarco
14876
14946
 
14877
14947
  class AssetViewEvent {
@@ -14930,10 +15000,14 @@ class AssetView {
14930
15000
 
14931
15001
  if( options.rootPath )
14932
15002
  {
14933
- if(options.rootPath.constructor !== String)
14934
- console.warn("Asset Root Path must be a String (now is " + path.constructor.name + ")");
15003
+ if( options.rootPath.constructor !== String )
15004
+ {
15005
+ console.warn( `Asset Root Path must be a String (now is a ${ path.constructor.name })` );
15006
+ }
14935
15007
  else
15008
+ {
14936
15009
  this.rootPath = options.rootPath;
15010
+ }
14937
15011
  }
14938
15012
 
14939
15013
  let div = document.createElement('div');
@@ -15302,7 +15376,7 @@ class AssetView {
15302
15376
  this.content.className = (isContentLayout ? "lexassetscontent" : "lexassetscontent list");
15303
15377
  let that = this;
15304
15378
 
15305
- const add_item = function(item) {
15379
+ const _addItem = function(item) {
15306
15380
 
15307
15381
  const type = item.type.charAt( 0 ).toUpperCase() + item.type.slice( 1 );
15308
15382
  const extension = LX.getExtension( item.id );
@@ -15327,20 +15401,27 @@ class AssetView {
15327
15401
  return;
15328
15402
  }
15329
15403
 
15404
+ const dialog = itemEl.closest('dialog');
15330
15405
  const rect = itemEl.getBoundingClientRect();
15331
15406
  const targetRect = e.target.getBoundingClientRect();
15332
- const parentRect = desc.parentElement.getBoundingClientRect();
15333
15407
 
15334
- let localOffsetX = targetRect.x - parentRect.x - ( targetRect.x - rect.x );
15335
- let localOffsetY = targetRect.y - parentRect.y - ( targetRect.y - rect.y );
15408
+ let localOffsetX = rect.x + e.offsetX;
15409
+ let localOffsetY = rect.y + e.offsetY;
15410
+
15411
+ if( dialog )
15412
+ {
15413
+ const dialogRect = dialog.getBoundingClientRect();
15414
+ localOffsetX -= dialogRect.x;
15415
+ localOffsetY -= dialogRect.y;
15416
+ }
15336
15417
 
15337
15418
  if( e.target.classList.contains( "lexassettitle" ) )
15338
15419
  {
15339
15420
  localOffsetY += ( targetRect.y - rect.y );
15340
15421
  }
15341
15422
 
15342
- desc.style.left = (localOffsetX + e.offsetX + 12) + "px";
15343
- desc.style.top = (localOffsetY + e.offsetY) + "px";
15423
+ desc.style.left = ( localOffsetX ) + "px";
15424
+ desc.style.top = ( localOffsetY - 36 ) + "px";
15344
15425
  });
15345
15426
 
15346
15427
  itemEl.addEventListener("mouseenter", () => {
@@ -15538,7 +15619,7 @@ class AssetView {
15538
15619
  } });
15539
15620
  }else
15540
15621
  {
15541
- item.domEl = add_item( item );
15622
+ item.domEl = _addItem( item );
15542
15623
  }
15543
15624
  }
15544
15625
 
@@ -15738,6 +15819,6 @@ class AssetView {
15738
15819
  }
15739
15820
  }
15740
15821
 
15741
- LX.AssetView = AssetView;
15742
-
15743
- export { ADD_CUSTOM_WIDGET, Area, AssetView, AssetViewEvent, Branch, LX, Menubar, Panel, Sidebar, Widget };
15822
+ LX.AssetView = AssetView;
15823
+
15824
+ export { ADD_CUSTOM_WIDGET, Area, AssetView, AssetViewEvent, Branch, LX, Menubar, Panel, Sidebar, Widget };