lexgui 0.1.28 → 0.1.30

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,12 +12,16 @@ 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.28",
15
+ version: "0.1.30",
16
16
  ready: false,
17
17
  components: [], // specific pre-build components
18
18
  signals: {} // events and triggers
19
19
  };
20
20
 
21
+ LX.MOUSE_LEFT_CLICK = 0;
22
+ LX.MOUSE_MIDDLE_CLICK = 1;
23
+ LX.MOUSE_RIGHT_CLICK = 2;
24
+
21
25
  LX.MOUSE_DOUBLE_CLICK = 2;
22
26
  LX.MOUSE_TRIPLE_CLICK = 3;
23
27
 
@@ -79,27 +83,31 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
79
83
 
80
84
  LX.getBase64Image = getBase64Image;
81
85
 
82
- function hexToRgb(string) {
83
- const red = parseInt(string.substring(1, 3), 16) / 255;
84
- const green = parseInt(string.substring(3, 5), 16) / 255;
85
- const blue = parseInt(string.substring(5, 7), 16) / 255;
86
- return [red, green, blue];
86
+ function hexToRgb( hexStr ) {
87
+ const red = parseInt( hexStr.substring( 1, 3 ), 16 ) / 255;
88
+ const green = parseInt( hexStr.substring( 3, 5 ), 16 ) / 255;
89
+ const blue = parseInt( hexStr.substring( 5, 7 ), 16 ) / 255;
90
+ return [ red, green, blue ];
87
91
  }
88
-
89
- function rgbToHex(rgb) {
92
+
93
+ LX.hexToRgb = hexToRgb;
94
+
95
+ function rgbToHex( rgb ) {
90
96
  let hex = "#";
91
- for(let c of rgb) {
92
- c = Math.floor(c * 255);
93
- hex += c.toString(16);
97
+ for( let c of rgb ) {
98
+ c = Math.floor( c * 255 );
99
+ hex += c.toString( 16 );
94
100
  }
95
101
  return hex;
96
102
  }
103
+
104
+ LX.rgbToHex = rgbToHex;
97
105
 
98
106
  function simple_guidGenerator() {
99
107
  var S4 = function() {
100
108
  return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
101
109
  };
102
- return (S4()+"-"+S4());
110
+ return (S4()+"-"+S4()+"-"+S4());
103
111
  }
104
112
 
105
113
  // Timer that works everywhere (from litegraph.js)
@@ -144,6 +152,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
144
152
  sub ( v, v0 = new vec2() ) { v0.set( this.x - v.x, this.y - v.y ); return v0; }
145
153
  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; }
146
154
  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; }
155
+ abs ( v0 = new vec2() ) { v0.set( Math.abs( this.x ), Math.abs( this.y ) ); return v0; }
147
156
  };
148
157
 
149
158
  LX.vec2 = vec2;
@@ -156,46 +165,58 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
156
165
  let offsetY;
157
166
  let currentTarget = null;
158
167
  let targetClass = options.targetClass;
159
-
160
- const moveFunc = (e) => {
161
- if(!currentTarget) return;
168
+
169
+ let id = LX.UTILS.uidGenerator();
170
+ domEl[ 'draggable-id' ] = id;
171
+
172
+ const defaultMoveFunc = e => {
173
+ if( !currentTarget ) return;
162
174
  let left = e.clientX - offsetX;
163
175
  let top = e.clientY - offsetY;
164
- if(left > 3 && (left + domEl.offsetWidth + 6) <= window.innerWidth)
176
+ if( left > 3 && ( left + domEl.offsetWidth + 6 ) <= window.innerWidth )
165
177
  domEl.style.left = left + 'px';
166
- if(top > 3 && (top + domEl.offsetHeight + 6) <= window.innerHeight)
178
+ if( top > 3 && ( top + domEl.offsetHeight + 6 ) <= window.innerHeight )
167
179
  domEl.style.top = top + 'px';
168
180
  };
169
-
170
- let onMove = options.onMove ?? moveFunc;
171
181
 
172
- domEl.setAttribute('draggable', true);
173
- domEl.addEventListener("mousedown", function(e) {
182
+ const customMoveFunc = e => {
183
+ if( !currentTarget ) return;
184
+ if( options.onMove )
185
+ options.onMove( currentTarget );
186
+ };
187
+
188
+ let onMove = options.onMove ? customMoveFunc : defaultMoveFunc;
189
+ let onDragStart = options.onDragStart;
190
+
191
+ domEl.setAttribute( 'draggable', true );
192
+ domEl.addEventListener( "mousedown", function( e ) {
174
193
  currentTarget = (e.target.classList.contains(targetClass) || !targetClass) ? e.target : null;
175
- });
194
+ } );
176
195
 
177
- domEl.addEventListener("dragstart", function(e) {
196
+ domEl.addEventListener( "dragstart", function( e ) {
178
197
  e.preventDefault();
179
198
  e.stopPropagation();
180
199
  e.stopImmediatePropagation();
181
- if(!currentTarget) return;
200
+ if( !currentTarget ) return;
182
201
  // Remove image when dragging
183
202
  var img = new Image();
184
203
  img.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=';
185
- e.dataTransfer.setDragImage(img, 0, 0);
204
+ e.dataTransfer.setDragImage( img, 0, 0 );
186
205
  e.dataTransfer.effectAllowed = "move";
187
206
  const rect = e.target.getBoundingClientRect();
188
207
  offsetX = e.clientX - rect.x;
189
208
  offsetY = e.clientY - rect.y;
190
- document.addEventListener("mousemove", onMove );
191
- }, false);
209
+ document.addEventListener( "mousemove", onMove );
210
+ if( onDragStart )
211
+ onDragStart( currentTarget, e );
212
+ }, false );
192
213
 
193
- document.addEventListener('mouseup', () => {
194
- if(currentTarget) {
214
+ document.addEventListener( 'mouseup', () => {
215
+ if( currentTarget ) {
195
216
  currentTarget = null;
196
- document.removeEventListener("mousemove", onMove );
217
+ document.removeEventListener( "mousemove", onMove );
197
218
  }
198
- });
219
+ } );
199
220
  }
200
221
 
201
222
  LX.makeDraggable = makeDraggable;
@@ -400,33 +421,38 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
400
421
 
401
422
  /**
402
423
  * @method init
403
- * @param {*} options
424
+ * @param {Object} options
404
425
  * container: Root location for the gui (default is the document body)
426
+ * id: Id of the main area
405
427
  * skip_default_area: Skip creation of main area
406
428
  */
407
429
 
408
- function init(options = {})
430
+ function init( options = { } )
409
431
  {
410
- if(this.ready)
432
+ if( this.ready )
411
433
  return this.main_area;
412
434
 
413
- // LexGUI root
414
- var root = document.createElement("div");
415
- root.id = "lexroot";
435
+ // LexGUI root
436
+
437
+ var root = document.createElement( 'div' );
438
+ root.id = "lexroot";
416
439
  root.tabIndex = -1;
417
440
 
418
- var modal = document.createElement("div");
441
+ var modal = document.createElement( 'div' );
419
442
  modal.id = "modal";
420
443
 
421
444
  this.modal = modal;
422
445
  this.root = root;
423
446
  this.container = document.body;
424
447
 
425
- this.modal.toggleAttribute('hidden', true);
426
- this.modal.toggle = function(force) { this.toggleAttribute('hidden', force); };
448
+ // this.modal.toggleAttribute( 'hidden', true );
449
+ // this.modal.toggle = function( force ) { this.toggleAttribute( 'hidden', force ); };
427
450
 
428
- if(options.container)
429
- this.container = document.getElementById(options.container);
451
+ this.modal.classList.add( 'hiddenOpacity' );
452
+ this.modal.toggle = function( force ) { this.classList.toggle( 'hiddenOpacity', force ); };
453
+
454
+ if( options.container )
455
+ this.container = document.getElementById( options.container );
430
456
 
431
457
  this.global_search = create_global_searchbar( this.container );
432
458
 
@@ -434,17 +460,17 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
434
460
  this.container.appendChild( root );
435
461
 
436
462
  // Disable drag icon
437
- root.addEventListener("dragover", function(e) {
463
+ root.addEventListener( 'dragover', function( e ) {
438
464
  e.preventDefault();
439
465
  }, false );
440
466
 
441
467
  // CSS fontawesome
442
- var head = document.getElementsByTagName('HEAD')[0];
443
- var link = document.createElement('link');
468
+ var head = document.getElementsByTagName( 'HEAD' )[ 0 ];
469
+ var link = document.createElement( 'link' );
444
470
  link.rel = 'stylesheet';
445
471
  link.type = 'text/css';
446
- link.href = 'https://use.fontawesome.com/releases/v6.4.2/css/all.css';
447
- head.appendChild(link);
472
+ link.href = 'https://use.fontawesome.com/releases/v6.5.1/css/all.css';
473
+ head.appendChild( link );
448
474
 
449
475
  // Global vars
450
476
  this.DEFAULT_NAME_WIDTH = "30%";
@@ -452,10 +478,10 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
452
478
  this.OPEN_CONTEXTMENU_ENTRY = 'click';
453
479
 
454
480
  this.ready = true;
455
- this.menubars = [];
481
+ this.menubars = [ ];
456
482
 
457
- if(!options.skip_default_area)
458
- this.main_area = new Area( {id: options.id ?? "mainarea"} );
483
+ if( !options.skip_default_area )
484
+ this.main_area = new Area( { id: options.id ?? 'mainarea' } );
459
485
 
460
486
  return this.main_area;
461
487
  }
@@ -1286,7 +1312,8 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
1286
1312
  selectable: b.selectable,
1287
1313
  selected: b.selected,
1288
1314
  icon: b.icon,
1289
- img: b.img
1315
+ img: b.img,
1316
+ className: b.class
1290
1317
  };
1291
1318
 
1292
1319
  if( group )
@@ -1496,7 +1523,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
1496
1523
 
1497
1524
  let container = document.createElement('div');
1498
1525
  container.className = "lexareatabs " + (options.fit ? "fit" : "row");
1499
-
1526
+
1500
1527
  const folding = options.folding ?? false;
1501
1528
  if(folding) container.classList.add("folding");
1502
1529
 
@@ -1531,7 +1558,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
1531
1558
 
1532
1559
  // Show on drop
1533
1560
  el.click();
1534
-
1561
+
1535
1562
  // Store info
1536
1563
  that.tabs[ el.dataset["name"] ] = content;
1537
1564
  });
@@ -1548,6 +1575,29 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
1548
1575
  this.tabs = {};
1549
1576
  this.tabDOMs = {};
1550
1577
 
1578
+ if( options.fit )
1579
+ {
1580
+ // Create movable element
1581
+ let mEl = document.createElement('span');
1582
+ mEl.className = "lexareatab thumb";
1583
+ this.thumb = mEl;
1584
+ this.root.appendChild( mEl );
1585
+
1586
+ const resizeObserver = new ResizeObserver((entries) => {
1587
+ const tabEl = this.thumb.item;
1588
+ if( !tabEl ) return;
1589
+ var transition = this.thumb.style.transition;
1590
+ this.thumb.style.transition = "none";
1591
+ this.thumb.style.transform = "translate( " + ( tabEl.childIndex * tabEl.offsetWidth ) + "px )";
1592
+ this.thumb.style.width = ( tabEl.offsetWidth - 5 ) + "px";
1593
+ this.thumb.style.height = ( tabEl.offsetHeight - 6 ) + "px";
1594
+ flushCss( this.thumb );
1595
+ this.thumb.style.transition = transition;
1596
+ });
1597
+
1598
+ resizeObserver.observe( this.area.root );
1599
+ }
1600
+
1551
1601
  // debug
1552
1602
  if(folding)
1553
1603
  {
@@ -1645,6 +1695,14 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
1645
1695
 
1646
1696
  if(options.onSelect)
1647
1697
  options.onSelect(e, tabEl.dataset.name);
1698
+
1699
+ if( this.thumb )
1700
+ {
1701
+ this.thumb.style.transform = "translate( " + ( tabEl.childIndex * tabEl.offsetWidth ) + "px )";
1702
+ this.thumb.style.width = ( tabEl.offsetWidth - 5 ) + "px";
1703
+ this.thumb.style.height = ( tabEl.offsetHeight - 6 ) + "px";
1704
+ this.thumb.item = tabEl;
1705
+ }
1648
1706
  });
1649
1707
 
1650
1708
  tabEl.addEventListener("contextmenu", e => {
@@ -1673,13 +1731,26 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
1673
1731
  });
1674
1732
 
1675
1733
  // Attach content
1734
+ tabEl.childIndex = ( this.root.childElementCount - 1 );
1676
1735
  this.root.appendChild( tabEl );
1677
1736
  this.area.attach( contentEl );
1678
1737
  this.tabDOMs[ name ] = tabEl;
1679
1738
  this.tabs[ name ] = content;
1680
1739
 
1681
1740
  setTimeout( () => {
1682
- if( options.onCreate ) options.onCreate.call(this, this.area.root.getBoundingClientRect());
1741
+
1742
+ if( options.onCreate ) {
1743
+ options.onCreate.call(this, this.area.root.getBoundingClientRect());
1744
+ }
1745
+
1746
+ if( isSelected && this.thumb )
1747
+ {
1748
+ this.thumb.style.transform = "translate( " + ( tabEl.childIndex * tabEl.offsetWidth ) + "px )";
1749
+ this.thumb.style.width = ( tabEl.offsetWidth - 5 ) + "px";
1750
+ this.thumb.style.height = ( tabEl.offsetHeight - 6 ) + "px";
1751
+ this.thumb.item = tabEl;
1752
+ }
1753
+
1683
1754
  }, 10 );
1684
1755
  }
1685
1756
 
@@ -2174,6 +2245,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
2174
2245
  * @param {*} options:
2175
2246
  * callback: Function to call on each item
2176
2247
  * bottom: Bool to set item at the bottom as helper button (not selectable)
2248
+ * className: Add class to the entry DOM element
2177
2249
  */
2178
2250
 
2179
2251
  add( key, options = {} ) {
@@ -2190,14 +2262,14 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
2190
2262
  }
2191
2263
 
2192
2264
  let entry = document.createElement( 'div' );
2193
- entry.className = "lexsidebarentry";
2265
+ entry.className = "lexsidebarentry " + ( options.className ?? "" );
2194
2266
  entry.id = pKey;
2195
- entry.title = key;
2196
2267
 
2197
2268
  if( options.bottom )
2198
2269
  {
2199
2270
  this.footer.appendChild( entry );
2200
- }else
2271
+ }
2272
+ else
2201
2273
  {
2202
2274
  this.root.appendChild( entry );
2203
2275
  }
@@ -2209,6 +2281,11 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
2209
2281
  button.innerHTML = "<i class='"+ (options.icon ?? "") + "'></i>";
2210
2282
  entry.appendChild( button );
2211
2283
 
2284
+ let desc = document.createElement( 'span' );
2285
+ desc.className = 'lexsidebarentrydesc';
2286
+ desc.innerHTML = key;
2287
+ entry.appendChild( desc );
2288
+
2212
2289
  entry.addEventListener("click", () => {
2213
2290
 
2214
2291
  const f = options.callback;
@@ -2224,6 +2301,23 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
2224
2301
 
2225
2302
  this.items.push( { name: pKey, domEl: entry, callback: options.callback } );
2226
2303
  }
2304
+
2305
+ /**
2306
+ * @method select
2307
+ * @param {String} name Element name to select
2308
+ */
2309
+
2310
+ select( name ) {
2311
+
2312
+ let pKey = name.replace( /\s/g, '' ).replaceAll( '.', '' );
2313
+
2314
+ const entry = this.items.find( v => v.name === pKey );
2315
+
2316
+ if( !entry )
2317
+ return;
2318
+
2319
+ entry.domEl.click();
2320
+ }
2227
2321
  };
2228
2322
 
2229
2323
  LX.SideBar = SideBar;
@@ -3116,7 +3210,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
3116
3210
 
3117
3211
  if( type != Widget.TITLE )
3118
3212
  {
3119
- element.style.width = "calc(100% - " + (this.current_branch || type == Widget.FILE ? 10 : 20) + "px)";
3213
+ element.style.width = "calc(100% - " + (this.current_branch || type == Widget.FILE || ( type == Widget.BUTTON && !name ) ? 10 : 20) + "px)";
3120
3214
  if( options.width ) {
3121
3215
  element.style.width = element.style.minWidth = options.width;
3122
3216
  }
@@ -3447,103 +3541,109 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
3447
3541
 
3448
3542
  addText( name, value, callback, options = {} ) {
3449
3543
 
3450
- let widget = this.create_widget(name, Widget.TEXT, options);
3544
+ let widget = this.create_widget( name, Widget.TEXT, options );
3451
3545
  widget.onGetValue = () => {
3452
3546
  return wValue.value;
3453
3547
  };
3454
- widget.onSetValue = (new_value) => {
3455
- this.disabled ? wValue.innerText = new_value : wValue.value = new_value;
3456
- Panel._dispatch_event(wValue, "focusout");
3548
+ widget.onSetValue = newValue => {
3549
+ this.disabled ? wValue.innerText = newValue : wValue.value = newValue;
3550
+ Panel._dispatch_event( wValue, "focusout" );
3457
3551
  };
3458
-
3552
+
3459
3553
  let element = widget.domEl;
3460
-
3554
+
3461
3555
  // Add reset functionality
3462
- if(widget.name && !(options.skipReset ?? false)) {
3463
- Panel._add_reset_property(element.domName, function() {
3556
+ if( widget.name && !( options.skipReset ?? false ) ) {
3557
+ Panel._add_reset_property( element.domName, function() {
3464
3558
  wValue.value = wValue.iValue;
3465
3559
  this.style.display = "none";
3466
- Panel._dispatch_event(wValue, "focusout");
3467
- });
3560
+ Panel._dispatch_event( wValue, "focusout" );
3561
+ } );
3468
3562
  }
3469
3563
 
3470
3564
  // Add widget value
3471
-
3472
- let container = document.createElement('div');
3473
- container.className = "lextext" + (options.warning ? " lexwarning" : "");
3565
+
3566
+ let container = document.createElement( 'div' );
3567
+ container.className = "lextext" + ( options.warning ? " lexwarning" : "" );
3474
3568
  container.style.width = options.inputWidth || "calc( 100% - " + LX.DEFAULT_NAME_WIDTH + " )";
3475
3569
  container.style.display = "flex";
3476
-
3477
- this.disabled = (options.disabled || options.warning) ?? ( options.url ? true : false );
3570
+
3571
+ this.disabled = ( options.disabled || options.warning ) ?? ( options.url ? true : false );
3478
3572
  let wValue = null;
3479
-
3573
+
3480
3574
  if( !this.disabled )
3481
3575
  {
3482
- wValue = document.createElement('input');
3576
+ wValue = document.createElement( 'input' );
3483
3577
  wValue.type = options.type || "";
3484
3578
  wValue.value = wValue.iValue = value || "";
3485
3579
  wValue.style.width = "100%";
3486
3580
  wValue.style.textAlign = options.float ?? "";
3487
3581
 
3488
- if(options.placeholder) wValue.setAttribute("placeholder", options.placeholder);
3582
+ if( options.placeholder )
3583
+ wValue.setAttribute( "placeholder", options.placeholder );
3489
3584
 
3490
- var resolve = (function(val, event) {
3491
- let btn = element.querySelector(".lexwidgetname .lexicon");
3492
- if(btn) btn.style.display = (val != wValue.iValue ? "block" : "none");
3493
- this._trigger( new IEvent(name, val, event), callback );
3494
- }).bind(this);
3585
+ var resolve = ( function( val, event ) {
3586
+ let btn = element.querySelector( ".lexwidgetname .lexicon" );
3587
+ if( btn ) btn.style.display = ( val != wValue.iValue ? "block" : "none" );
3588
+ this._trigger( new IEvent( name, val, event ), callback );
3589
+ }).bind( this );
3495
3590
 
3496
3591
  const trigger = options.trigger ?? 'default';
3497
3592
 
3498
- if(trigger == 'default')
3593
+ if( trigger == 'default' )
3499
3594
  {
3500
- wValue.addEventListener("keyup", function(e){
3595
+ wValue.addEventListener( "keyup", function( e ){
3501
3596
  if(e.key == 'Enter')
3502
- resolve(e.target.value, e);
3597
+ resolve( e.target.value, e );
3503
3598
  });
3504
- wValue.addEventListener("focusout", function(e){
3505
- resolve(e.target.value, e);
3599
+ wValue.addEventListener( "focusout", function( e ){
3600
+ resolve( e.target.value, e );
3506
3601
  });
3507
3602
  }
3508
- else if(trigger == 'input')
3603
+ else if( trigger == 'input' )
3509
3604
  {
3510
- wValue.addEventListener("input", function(e){
3511
- resolve(e.target.value, e);
3605
+ wValue.addEventListener("input", function( e ){
3606
+ resolve( e.target.value, e );
3512
3607
  });
3513
3608
  }
3514
3609
 
3515
- if(options.icon)
3610
+ wValue.addEventListener( "mousedown", function( e ){
3611
+ e.stopImmediatePropagation();
3612
+ e.stopPropagation();
3613
+ });
3614
+
3615
+ if( options.icon )
3516
3616
  {
3517
- let icon = document.createElement('a');
3617
+ let icon = document.createElement( 'a' );
3518
3618
  icon.className = "inputicon " + options.icon;
3519
- container.appendChild(icon);
3619
+ container.appendChild( icon );
3520
3620
  }
3521
-
3621
+
3522
3622
  } else
3523
3623
  {
3524
- wValue = document.createElement(options.url ? 'a' : 'div');
3525
- if(options.url)
3624
+ wValue = document.createElement( options.url ? 'a' : 'div' );
3625
+ if( options.url )
3526
3626
  {
3527
3627
  wValue.href = options.url;
3528
3628
  wValue.target = "_blank";
3529
3629
  }
3530
3630
  const icon = options.warning ? '<i class="fa-solid fa-triangle-exclamation"></i>' : '';
3531
- wValue.innerHTML = (icon + value) || "";
3631
+ wValue.innerHTML = ( icon + value ) || "";
3532
3632
  wValue.style.width = "100%";
3533
3633
  wValue.style.textAlign = options.float ?? "";
3534
3634
  }
3535
-
3536
- Object.assign(wValue.style, options.style ?? {});
3537
-
3538
- container.appendChild(wValue);
3539
- element.appendChild(container);
3635
+
3636
+ Object.assign( wValue.style, options.style ?? {} );
3637
+
3638
+ container.appendChild( wValue );
3639
+ element.appendChild( container );
3540
3640
 
3541
3641
  // Remove branch padding and margins
3542
- if(!widget.name) {
3642
+ if( !widget.name ) {
3543
3643
  element.className += " noname";
3544
3644
  container.style.width = "100%";
3545
3645
  }
3546
-
3646
+
3547
3647
  return widget;
3548
3648
  }
3549
3649
 
@@ -3961,10 +4061,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
3961
4061
  delete list.unfocus_event;
3962
4062
  return;
3963
4063
  }
3964
- let container = selectedOption.parentElement.parentElement.parentElement.parentElement; // there must be a nicer way...
3965
- let rect = event.currentTarget.getBoundingClientRect();
3966
- let y_pos = container.classList.contains('lexdialog') ? rect.top - 5 + rect.height : rect.y + rect.height - 5;
3967
- element.querySelector(".lexoptions").style.top = y_pos + 'px';
4064
+ element.querySelector(".lexoptions").style.top = (selectedOption.offsetTop + selectedOption.offsetHeight) + 'px';
3968
4065
  element.querySelector(".lexoptions").style.width = (event.currentTarget.clientWidth) + 'px';
3969
4066
  element.querySelector(".lexoptions").toggleAttribute('hidden');
3970
4067
  list.focus();
@@ -4373,7 +4470,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
4373
4470
  buttonName = "Add item";
4374
4471
  buttonName += "<a class='fa-solid fa-plus' style='float:right; margin-right: 3px; margin-top: 2px;'></a>";
4375
4472
  this.addButton(null, buttonName, (v, event) => {
4376
- values.push( "" );
4473
+ values.push( options.innerValues ? options.innerValues[ 0 ] : "" );
4377
4474
  updateItems();
4378
4475
  this._trigger( new IEvent(name, values, event), callback );
4379
4476
  }, { buttonClass: 'array' });
@@ -4892,6 +4989,8 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
4892
4989
  document.body.classList.add('nocursor');
4893
4990
  document.body.classList.add('noevents');
4894
4991
  drag_icon.classList.remove('hidden');
4992
+ e.stopImmediatePropagation();
4993
+ e.stopPropagation();
4895
4994
  }
4896
4995
 
4897
4996
  function inner_mousemove(e) {
@@ -5064,6 +5163,8 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5064
5163
  document.body.classList.add('nocursor');
5065
5164
  document.body.classList.add('noevents');
5066
5165
  drag_icon.classList.remove('hidden');
5166
+ e.stopImmediatePropagation();
5167
+ e.stopPropagation();
5067
5168
  }
5068
5169
 
5069
5170
  function inner_mousemove(e) {
@@ -5243,16 +5344,17 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5243
5344
  * @param {Function} callback Callback function on change
5244
5345
  * @param {*} options:
5245
5346
  * local: Ask for local file
5347
+ * read: Return the file itself (False) or the contents (True)
5246
5348
  * type: type to read as [text (Default), buffer, bin, url]
5247
5349
  */
5248
5350
 
5249
5351
  addFile( name, callback, options = { } ) {
5250
5352
 
5251
- if(!name) {
5252
- throw("Set Widget Name!");
5353
+ if( !name ) {
5354
+ throw( "Set Widget Name!" );
5253
5355
  }
5254
5356
 
5255
- let widget = this.create_widget(name, Widget.FILE, options);
5357
+ let widget = this.create_widget( name, Widget.FILE, options );
5256
5358
  let element = widget.domEl;
5257
5359
 
5258
5360
  let local = options.local ?? true;
@@ -5260,31 +5362,36 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5260
5362
  let read = options.read ?? true;
5261
5363
 
5262
5364
  // Create hidden input
5263
- let input = document.createElement('input');
5365
+ let input = document.createElement( 'input' );
5264
5366
  input.style.width = "calc( 100% - " + LX.DEFAULT_NAME_WIDTH + " - 10%)";
5265
5367
  input.type = 'file';
5266
- if(options.placeholder)
5368
+
5369
+ if( options.placeholder )
5267
5370
  input.placeholder = options.placeholder;
5268
5371
 
5269
- input.addEventListener('change', function(e) {
5372
+ input.addEventListener( 'change', function( e ) {
5373
+
5270
5374
  const files = e.target.files;
5271
5375
  if( !files.length ) return;
5272
- if(read)
5376
+ if( read )
5273
5377
  {
5378
+ if( options.onBeforeRead )
5379
+ options.onBeforeRead();
5380
+
5274
5381
  const reader = new FileReader();
5275
5382
 
5276
- if(type === 'text') reader.readAsText(files[0]);
5277
- else if(type === 'buffer') reader.readAsArrayBuffer(files[0]);
5278
- else if(type === 'bin') reader.readAsBinaryString(files[0]);
5279
- else if(type === 'url') reader.readAsDataURL(files[0]);
5383
+ if( type === 'text' ) reader.readAsText( files[ 0 ] );
5384
+ else if( type === 'buffer' ) reader.readAsArrayBuffer( files[ 0 ] );
5385
+ else if( type === 'bin' ) reader.readAsBinaryString( files[ 0 ] );
5386
+ else if( type === 'url' ) reader.readAsDataURL( files[ 0 ] );
5280
5387
 
5281
- reader.onload = (e) => { callback.call( this, e.target.result, files[0] ) } ;
5388
+ reader.onload = e => { callback.call( this, e.target.result, files[ 0 ] ) } ;
5282
5389
  }
5283
- else callback(files[0]);
5284
-
5390
+ else
5391
+ callback( files[ 0 ] );
5285
5392
  });
5286
5393
 
5287
- element.appendChild(input);
5394
+ element.appendChild( input );
5288
5395
 
5289
5396
  this.queue( element );
5290
5397
 
@@ -5292,9 +5399,9 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5292
5399
  {
5293
5400
  this.addButton(null, "<a style='margin-top: 0px;' class='fa-solid fa-gear'></a>", () => {
5294
5401
 
5295
- new Dialog("Load Settings", p => {
5296
- p.addDropdown("Type", ['text', 'buffer', 'bin', 'url'], type, v => { type = v } );
5297
- p.addButton(null, "Reload", v => { input.dispatchEvent( new Event('change') ) } );
5402
+ new Dialog( "Load Settings", p => {
5403
+ p.addDropdown( "Type", [ 'text', 'buffer', 'bin', 'url' ], type, v => { type = v } );
5404
+ p.addButton( null, "Reload", v => { input.dispatchEvent( new Event( 'change' ) ) } );
5298
5405
  });
5299
5406
 
5300
5407
  }, { className: "micro", skipInlineCount: true });
@@ -5848,6 +5955,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5848
5955
  }
5849
5956
 
5850
5957
  destroy() {
5958
+
5851
5959
  this.root.remove();
5852
5960
  }
5853
5961
 
@@ -5862,6 +5970,14 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5862
5970
  this.root.style.left = x + "px";
5863
5971
  this.root.style.top = y + "px";
5864
5972
  }
5973
+
5974
+ setTitle( title ) {
5975
+
5976
+ const titleDOM = this.root.querySelector( '.lexdialogtitle' );
5977
+ if( !titleDOM )
5978
+ return;
5979
+ titleDOM.innerText = title;
5980
+ }
5865
5981
  }
5866
5982
 
5867
5983
  LX.Dialog = Dialog;
@@ -5891,8 +6007,10 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5891
6007
 
5892
6008
  // Custom
5893
6009
  this.root.classList.add( "pocket" );
5894
- this.root.style.left = "calc(100% - " + (this.root.offsetWidth + 6) + "px)";
5895
- this.root.style.top = "0px";
6010
+ if( !options.position ) {
6011
+ this.root.style.left = "calc(100% - " + (this.root.offsetWidth + 6) + "px)";
6012
+ this.root.style.top = "0px";
6013
+ }
5896
6014
  this.panel.root.style.width = "calc( 100% - 12px )";
5897
6015
  this.panel.root.style.height = "calc( 100% - 40px )";
5898
6016
  this.dock_pos = PocketDialog.TOP;
@@ -5931,7 +6049,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5931
6049
  this.root.style.top = "calc(100% - " + (this.root.offsetHeight + 6) + "px)";
5932
6050
  break;
5933
6051
  case 'l':
5934
- this.root.style.left = "0px";
6052
+ this.root.style.left = options.position ? options.position[ 1 ] : "0px";
5935
6053
  break;
5936
6054
  }
5937
6055
  }
@@ -6036,7 +6154,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
6036
6154
  contextmenu.style.marginTop = 3.5 - c.offsetHeight + "px";
6037
6155
 
6038
6156
  // Set final width
6039
- contextmenu.style.width = contextmenu.offsetWidth + "px";
6157
+ // contextmenu.style.width = contextmenu.offsetWidth + "px";
6040
6158
  this._adjust_position( contextmenu, 6, true );
6041
6159
  }
6042
6160
 
@@ -7484,9 +7602,15 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
7484
7602
  configurable: true
7485
7603
  });
7486
7604
 
7487
- Element.prototype.insertChildAtIndex = function(child, index = Infinity) {
7488
- if (index >= this.children.length) this.appendChild(child);
7489
- else this.insertBefore(child, this.children[index]);
7605
+ Element.prototype.insertChildAtIndex = function( child, index = Infinity ) {
7606
+ if ( index >= this.children.length ) this.appendChild( child );
7607
+ else this.insertBefore( child, this.children[index] );
7608
+ }
7609
+
7610
+ Element.prototype.hasClass = function( list ) {
7611
+ list = [].concat( list );
7612
+ var r = list.filter( v => this.classList.contains( v ) );
7613
+ return !!r.length;
7490
7614
  }
7491
7615
 
7492
7616
  Element.prototype.getComputedSize = function() {
@@ -7502,7 +7626,14 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
7502
7626
  compareThreshold( v, p, n, t ) { return Math.abs(v - p) >= t || Math.abs(v - n) >= t },
7503
7627
  compareThresholdRange( v0, v1, t0, t1 ) { return v0 >= t0 && v0 <= t1 || v1 >= t0 && v1 <= t1 || v0 <= t0 && v1 >= t1},
7504
7628
  clamp (num, min, max) { return Math.min(Math.max(num, min), max) },
7505
-
7629
+ uidGenerator: simple_guidGenerator,
7630
+ deleteElement( el ) { if( el ) el.remove(); },
7631
+ flushCss(element) {
7632
+ // By reading the offsetHeight property, we are forcing
7633
+ // the browser to flush the pending CSS changes (which it
7634
+ // does to ensure the value obtained is accurate).
7635
+ element.offsetHeight;
7636
+ },
7506
7637
  getControlPoints( x0, y0, x1, y1, x2, y2 ,t ) {
7507
7638
 
7508
7639
  // x0,y0,x1,y1 are the coordinates of the end (knot) pts of this segment
@@ -7527,7 +7658,6 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
7527
7658
 
7528
7659
  return [p1x,p1y,p2x,p2y]
7529
7660
  },
7530
-
7531
7661
  drawSpline( ctx, pts, t ) {
7532
7662
 
7533
7663
  ctx.save();