lexgui 0.1.27 → 0.1.29

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.27",
15
+ version: "0.1.29",
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)
@@ -142,59 +150,73 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
142
150
  set ( x, y ) { this.x = x; this.y = y; }
143
151
  add ( v, v0 = new vec2() ) { v0.set( this.x + v.x, this.y + v.y ); return v0; }
144
152
  sub ( v, v0 = new vec2() ) { v0.set( this.x - v.x, this.y - v.y ); return v0; }
145
- mul ( v, v0 = new vec2() ) { if( v.constructor == Number ) { v = new vec2(v) } v = v0.set( this.x * v.x, this.y * v.y ); return v0; }
146
- div ( v, v0 = new vec2() ) { v0.set( this.x / v.x, this.y / v.y ); return v0; }
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; }
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;
150
159
 
151
160
  // Other utils
152
161
 
153
- function makeDraggable( domEl, targetClass ) {
162
+ function makeDraggable( domEl, options = { } ) {
154
163
 
155
164
  let offsetX;
156
165
  let offsetY;
157
166
  let currentTarget = null;
167
+ let targetClass = options.targetClass;
168
+
169
+ let id = LX.UTILS.uidGenerator();
170
+ domEl[ 'draggable-id' ] = id;
171
+
172
+ const defaultMoveFunc = e => {
173
+ if( !currentTarget ) return;
174
+ let left = e.clientX - offsetX;
175
+ let top = e.clientY - offsetY;
176
+ if( left > 3 && ( left + domEl.offsetWidth + 6 ) <= window.innerWidth )
177
+ domEl.style.left = left + 'px';
178
+ if( top > 3 && ( top + domEl.offsetHeight + 6 ) <= window.innerHeight )
179
+ domEl.style.top = top + 'px';
180
+ };
181
+
182
+ const customMoveFunc = e => {
183
+ if( !currentTarget ) return;
184
+ if( options.onMove )
185
+ options.onMove( currentTarget );
186
+ };
158
187
 
159
- domEl.setAttribute('draggable', true);
160
- domEl.addEventListener("mousedown", function(e) {
161
- // e.stopPropagation();
162
- // e.stopImmediatePropagation();
188
+ let onMove = options.onMove ? customMoveFunc : defaultMoveFunc;
189
+ let onDragStart = options.onDragStart;
190
+
191
+ domEl.setAttribute( 'draggable', true );
192
+ domEl.addEventListener( "mousedown", function( e ) {
163
193
  currentTarget = (e.target.classList.contains(targetClass) || !targetClass) ? e.target : null;
164
- });
194
+ } );
165
195
 
166
- domEl.addEventListener("dragstart", function(e) {
196
+ domEl.addEventListener( "dragstart", function( e ) {
167
197
  e.preventDefault();
168
198
  e.stopPropagation();
169
199
  e.stopImmediatePropagation();
170
- if(!currentTarget) return;
200
+ if( !currentTarget ) return;
171
201
  // Remove image when dragging
172
202
  var img = new Image();
173
203
  img.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=';
174
- e.dataTransfer.setDragImage(img, 0, 0);
204
+ e.dataTransfer.setDragImage( img, 0, 0 );
175
205
  e.dataTransfer.effectAllowed = "move";
176
206
  const rect = e.target.getBoundingClientRect();
177
207
  offsetX = e.clientX - rect.x;
178
208
  offsetY = e.clientY - rect.y;
179
- document.addEventListener("mousemove", moveFunc );
180
- }, false);
209
+ document.addEventListener( "mousemove", onMove );
210
+ if( onDragStart )
211
+ onDragStart( currentTarget, e );
212
+ }, false );
181
213
 
182
- const moveFunc = (e) => {
183
- if(!currentTarget) return;
184
- let left = e.clientX - offsetX;
185
- let top = e.clientY - offsetY;
186
- if(left > 3 && (left + domEl.offsetWidth + 6) <= window.innerWidth)
187
- domEl.style.left = left + 'px';
188
- if(top > 3 && (top + domEl.offsetHeight + 6) <= window.innerHeight)
189
- domEl.style.top = top + 'px';
190
- };
191
-
192
- document.addEventListener('mouseup', () => {
193
- if(currentTarget) {
214
+ document.addEventListener( 'mouseup', () => {
215
+ if( currentTarget ) {
194
216
  currentTarget = null;
195
- document.removeEventListener("mousemove", moveFunc );
217
+ document.removeEventListener( "mousemove", onMove );
196
218
  }
197
- });
219
+ } );
198
220
  }
199
221
 
200
222
  LX.makeDraggable = makeDraggable;
@@ -333,15 +355,20 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
333
355
 
334
356
  const propagate_add = ( item, filter, path ) => {
335
357
 
336
- const key = Object.keys(item)[0];
337
- if( (path + key).toLowerCase().includes(filter) ) {
338
- if(item.callback)
339
- add_element(key, item.callback, path, item);
358
+ const key = Object.keys( item )[ 0 ];
359
+ let name = item.name ?? path + key;
360
+ if( name.toLowerCase().includes( filter ) ) {
361
+ if( item.callback )
362
+ add_element( item.name ?? key, item.callback, path, item );
340
363
  }
341
364
 
365
+ // is sidebar..
366
+ if( item.name )
367
+ return;
368
+
342
369
  path += key + " > ";
343
370
 
344
- for( let c of item[key] )
371
+ for( let c of item[ key ] )
345
372
  propagate_add( c, filter, path );
346
373
  };
347
374
 
@@ -351,7 +378,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
351
378
 
352
379
  for( let m of LX.menubars )
353
380
  for( let i of m.items ) {
354
- propagate_add( i, filter, "");
381
+ propagate_add( i, filter, "" );
355
382
  }
356
383
 
357
384
  if( LX.has('CodeEditor') )
@@ -869,7 +896,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
869
896
  }
870
897
 
871
898
  // Create areas
872
- var area1 = new Area({ no_append: true, className: "split" + (options.menubar ? "" : " origin") });
899
+ var area1 = new Area({ no_append: true, className: "split" + (options.menubar || options.sidebar ? "" : " origin") });
873
900
  var area2 = new Area({ no_append: true, className: "split"});
874
901
 
875
902
  area1.parentArea = this;
@@ -1190,16 +1217,11 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
1190
1217
  addMenubar( callback, options = {} ) {
1191
1218
 
1192
1219
  let menubar = new Menubar(options);
1193
- LX.menubars.push( menubar );
1194
1220
 
1195
1221
  if(callback) callback( menubar );
1196
1222
 
1197
- // Hack to get content height
1198
- // let d = document.createElement('div');
1199
- // d.appendChild(menubar.root);
1200
- // document.body.appendChild(d);
1201
- // const height = menubar.root.clientHeight;
1202
- // d.remove();
1223
+ LX.menubars.push( menubar );
1224
+
1203
1225
  const height = 48; // pixels
1204
1226
 
1205
1227
  const [bar, content] = this.split({type: 'vertical', sizes: [height, null], resize: false, menubar: true});
@@ -1209,6 +1231,27 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
1209
1231
  return menubar;
1210
1232
  }
1211
1233
 
1234
+ /**
1235
+ * @method addSidebar
1236
+ * @param {Function} callback Function to fill the sidebar
1237
+ */
1238
+
1239
+ addSidebar( callback, options = {} ) {
1240
+
1241
+ let sidebar = new SideBar( options );
1242
+
1243
+ if( callback ) callback( sidebar );
1244
+
1245
+ LX.menubars.push( sidebar );
1246
+
1247
+ const width = 64; // pixels
1248
+
1249
+ const [bar, content] = this.split( { type: 'horizontal', sizes: [ width, null ], resize: false, sidebar: true } );
1250
+ bar.attach( sidebar );
1251
+ bar.is_sidebar = true;
1252
+ return sidebar;
1253
+ }
1254
+
1212
1255
  /**
1213
1256
  * @method addOverlayButtons
1214
1257
  * @param {Array} buttons Buttons info
@@ -1782,7 +1825,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
1782
1825
  let entry = document.createElement('div');
1783
1826
  entry.className = "lexmenuentry";
1784
1827
  entry.id = pKey;
1785
- entry.innerText = key;
1828
+ entry.innerHTML = "<span>" + key + "</span>";
1786
1829
  if(options.position == "left") {
1787
1830
  this.root.prepend( entry );
1788
1831
  }
@@ -1806,7 +1849,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
1806
1849
  var rect = c.getBoundingClientRect();
1807
1850
  contextmenu.style.left = (isSubMenu ? rect.width : rect.left) + "px";
1808
1851
  // Entries use css to set top relative to parent
1809
- contextmenu.style.top = (isSubMenu ? 0 : rect.bottom) + "px";
1852
+ contextmenu.style.top = (isSubMenu ? 0 : rect.bottom - 4) + "px";
1810
1853
  c.appendChild( contextmenu );
1811
1854
 
1812
1855
  contextmenu.focus();
@@ -1932,11 +1975,16 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
1932
1975
  return;
1933
1976
  }
1934
1977
 
1978
+ // Manage selected
1979
+ this.root.querySelectorAll(".lexmenuentry").forEach( e => e.classList.remove( 'selected' ) );
1980
+ entry.classList.add( "selected" );
1981
+
1935
1982
  this.root.querySelectorAll(".lexcontextmenu").forEach(e => e.remove());
1936
1983
  create_submenu( item, key, entry, -1 );
1937
1984
  });
1938
1985
 
1939
1986
  entry.addEventListener("mouseleave", () => {
1987
+ this.root.querySelectorAll(".lexmenuentry").forEach( e => e.classList.remove( 'selected' ) );
1940
1988
  this.root.querySelectorAll(".lexcontextmenu").forEach(e => e.remove());
1941
1989
  });
1942
1990
  }
@@ -2124,6 +2172,83 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
2124
2172
 
2125
2173
  LX.Menubar = Menubar;
2126
2174
 
2175
+ /**
2176
+ * @class SideBar
2177
+ */
2178
+
2179
+ class SideBar {
2180
+
2181
+ constructor( options = {} ) {
2182
+
2183
+ this.root = document.createElement( 'div' );
2184
+ this.root.className = "lexsidebar";
2185
+
2186
+ this.footer = document.createElement( 'div' );
2187
+ this.footer.className = "lexsidebarfooter";
2188
+ this.root.appendChild( this.footer );
2189
+
2190
+ this.items = [ ];
2191
+ }
2192
+
2193
+ /**
2194
+ * @method add
2195
+ * @param {*} options:
2196
+ * callback: Function to call on each item
2197
+ * bottom: Bool to set item at the bottom as helper button (not selectable)
2198
+ */
2199
+
2200
+ add( key, options = {} ) {
2201
+
2202
+ if( options.constructor == Function )
2203
+ options = { callback: options };
2204
+
2205
+ let pKey = key.replace( /\s/g, '' ).replaceAll( '.', '' );
2206
+
2207
+ if( this.items.findIndex( (v, i) => v.key == pKey ) > -1 )
2208
+ {
2209
+ console.warn( `'${key}' already created in Sidebar` );
2210
+ return;
2211
+ }
2212
+
2213
+ let entry = document.createElement( 'div' );
2214
+ entry.className = "lexsidebarentry";
2215
+ entry.id = pKey;
2216
+ entry.title = key;
2217
+
2218
+ if( options.bottom )
2219
+ {
2220
+ this.footer.appendChild( entry );
2221
+ }else
2222
+ {
2223
+ this.root.appendChild( entry );
2224
+ }
2225
+
2226
+ // Reappend footer in root
2227
+ this.root.appendChild( this.footer );
2228
+
2229
+ let button = document.createElement( 'button' );
2230
+ button.innerHTML = "<i class='"+ (options.icon ?? "") + "'></i>";
2231
+ entry.appendChild( button );
2232
+
2233
+ entry.addEventListener("click", () => {
2234
+
2235
+ const f = options.callback;
2236
+ if( f ) f.call( this, key, entry );
2237
+
2238
+ // Manage selected
2239
+ if( !options.bottom )
2240
+ {
2241
+ this.root.querySelectorAll(".lexsidebarentry").forEach( e => e.classList.remove( 'selected' ) );
2242
+ entry.classList.add( "selected" );
2243
+ }
2244
+ });
2245
+
2246
+ this.items.push( { name: pKey, domEl: entry, callback: options.callback } );
2247
+ }
2248
+ };
2249
+
2250
+ LX.SideBar = SideBar;
2251
+
2127
2252
  /**
2128
2253
  * @class Widget
2129
2254
  */
@@ -3343,103 +3468,109 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
3343
3468
 
3344
3469
  addText( name, value, callback, options = {} ) {
3345
3470
 
3346
- let widget = this.create_widget(name, Widget.TEXT, options);
3471
+ let widget = this.create_widget( name, Widget.TEXT, options );
3347
3472
  widget.onGetValue = () => {
3348
3473
  return wValue.value;
3349
3474
  };
3350
- widget.onSetValue = (new_value) => {
3351
- this.disabled ? wValue.innerText = new_value : wValue.value = new_value;
3352
- Panel._dispatch_event(wValue, "focusout");
3475
+ widget.onSetValue = newValue => {
3476
+ this.disabled ? wValue.innerText = newValue : wValue.value = newValue;
3477
+ Panel._dispatch_event( wValue, "focusout" );
3353
3478
  };
3354
-
3479
+
3355
3480
  let element = widget.domEl;
3356
-
3481
+
3357
3482
  // Add reset functionality
3358
- if(widget.name && !(options.skipReset ?? false)) {
3359
- Panel._add_reset_property(element.domName, function() {
3483
+ if( widget.name && !( options.skipReset ?? false ) ) {
3484
+ Panel._add_reset_property( element.domName, function() {
3360
3485
  wValue.value = wValue.iValue;
3361
3486
  this.style.display = "none";
3362
- Panel._dispatch_event(wValue, "focusout");
3363
- });
3487
+ Panel._dispatch_event( wValue, "focusout" );
3488
+ } );
3364
3489
  }
3365
3490
 
3366
3491
  // Add widget value
3367
-
3368
- let container = document.createElement('div');
3369
- container.className = "lextext" + (options.warning ? " lexwarning" : "");
3492
+
3493
+ let container = document.createElement( 'div' );
3494
+ container.className = "lextext" + ( options.warning ? " lexwarning" : "" );
3370
3495
  container.style.width = options.inputWidth || "calc( 100% - " + LX.DEFAULT_NAME_WIDTH + " )";
3371
3496
  container.style.display = "flex";
3372
-
3373
- this.disabled = (options.disabled || options.warning) ?? ( options.url ? true : false );
3497
+
3498
+ this.disabled = ( options.disabled || options.warning ) ?? ( options.url ? true : false );
3374
3499
  let wValue = null;
3375
-
3500
+
3376
3501
  if( !this.disabled )
3377
3502
  {
3378
- wValue = document.createElement('input');
3503
+ wValue = document.createElement( 'input' );
3379
3504
  wValue.type = options.type || "";
3380
3505
  wValue.value = wValue.iValue = value || "";
3381
3506
  wValue.style.width = "100%";
3382
3507
  wValue.style.textAlign = options.float ?? "";
3383
3508
 
3384
- if(options.placeholder) wValue.setAttribute("placeholder", options.placeholder);
3509
+ if( options.placeholder )
3510
+ wValue.setAttribute( "placeholder", options.placeholder );
3385
3511
 
3386
- var resolve = (function(val, event) {
3387
- let btn = element.querySelector(".lexwidgetname .lexicon");
3388
- if(btn) btn.style.display = (val != wValue.iValue ? "block" : "none");
3389
- this._trigger( new IEvent(name, val, event), callback );
3390
- }).bind(this);
3512
+ var resolve = ( function( val, event ) {
3513
+ let btn = element.querySelector( ".lexwidgetname .lexicon" );
3514
+ if( btn ) btn.style.display = ( val != wValue.iValue ? "block" : "none" );
3515
+ this._trigger( new IEvent( name, val, event ), callback );
3516
+ }).bind( this );
3391
3517
 
3392
3518
  const trigger = options.trigger ?? 'default';
3393
3519
 
3394
- if(trigger == 'default')
3520
+ if( trigger == 'default' )
3395
3521
  {
3396
- wValue.addEventListener("keyup", function(e){
3522
+ wValue.addEventListener( "keyup", function( e ){
3397
3523
  if(e.key == 'Enter')
3398
- resolve(e.target.value, e);
3524
+ resolve( e.target.value, e );
3399
3525
  });
3400
- wValue.addEventListener("focusout", function(e){
3401
- resolve(e.target.value, e);
3526
+ wValue.addEventListener( "focusout", function( e ){
3527
+ resolve( e.target.value, e );
3402
3528
  });
3403
3529
  }
3404
- else if(trigger == 'input')
3530
+ else if( trigger == 'input' )
3405
3531
  {
3406
- wValue.addEventListener("input", function(e){
3407
- resolve(e.target.value, e);
3532
+ wValue.addEventListener("input", function( e ){
3533
+ resolve( e.target.value, e );
3408
3534
  });
3409
3535
  }
3410
3536
 
3411
- if(options.icon)
3537
+ wValue.addEventListener( "mousedown", function( e ){
3538
+ e.stopImmediatePropagation();
3539
+ e.stopPropagation();
3540
+ });
3541
+
3542
+ if( options.icon )
3412
3543
  {
3413
- let icon = document.createElement('a');
3544
+ let icon = document.createElement( 'a' );
3414
3545
  icon.className = "inputicon " + options.icon;
3415
- container.appendChild(icon);
3546
+ container.appendChild( icon );
3416
3547
  }
3417
-
3548
+
3418
3549
  } else
3419
3550
  {
3420
- wValue = document.createElement(options.url ? 'a' : 'div');
3421
- if(options.url)
3551
+ wValue = document.createElement( options.url ? 'a' : 'div' );
3552
+ if( options.url )
3422
3553
  {
3423
3554
  wValue.href = options.url;
3424
3555
  wValue.target = "_blank";
3425
3556
  }
3426
3557
  const icon = options.warning ? '<i class="fa-solid fa-triangle-exclamation"></i>' : '';
3427
- wValue.innerHTML = (icon + value) || "";
3558
+ wValue.innerHTML = ( icon + value ) || "";
3428
3559
  wValue.style.width = "100%";
3429
3560
  wValue.style.textAlign = options.float ?? "";
3430
3561
  }
3431
-
3432
- Object.assign(wValue.style, options.style ?? {});
3433
-
3434
- container.appendChild(wValue);
3435
- element.appendChild(container);
3562
+
3563
+ Object.assign( wValue.style, options.style ?? {} );
3564
+
3565
+ container.appendChild( wValue );
3566
+ element.appendChild( container );
3436
3567
 
3437
3568
  // Remove branch padding and margins
3438
- if(!widget.name) {
3569
+ if( !widget.name ) {
3439
3570
  element.className += " noname";
3440
3571
  container.style.width = "100%";
3441
3572
  }
3442
-
3573
+
3443
3574
  return widget;
3444
3575
  }
3445
3576
 
@@ -3848,7 +3979,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
3848
3979
 
3849
3980
  // Add dropdown widget button
3850
3981
  let buttonName = value;
3851
- buttonName += "<a class='fa-solid fa-angle-down' style='float:right; margin-right: 6px;'></a>";
3982
+ buttonName += "<a class='fa-solid fa-angle-down' style='float:right; margin-right: 3px;'></a>";
3852
3983
 
3853
3984
  this.queue(container);
3854
3985
 
@@ -3857,11 +3988,8 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
3857
3988
  delete list.unfocus_event;
3858
3989
  return;
3859
3990
  }
3860
- let container = selectedOption.parentElement.parentElement.parentElement.parentElement; // there must be a nicer way...
3861
- let rect = event.currentTarget.getBoundingClientRect();
3862
- let y_pos = container.classList.contains('lexdialog') ? rect.top - 5 + rect.height : rect.y + rect.height - 5;
3863
- element.querySelector(".lexoptions").style.top = y_pos + 'px';
3864
- element.querySelector(".lexoptions").style.width = (event.currentTarget.clientWidth) + 2 + 'px';
3991
+ element.querySelector(".lexoptions").style.top = (selectedOption.offsetTop + selectedOption.offsetHeight) + 'px';
3992
+ element.querySelector(".lexoptions").style.width = (event.currentTarget.clientWidth) + 'px';
3865
3993
  element.querySelector(".lexoptions").toggleAttribute('hidden');
3866
3994
  list.focus();
3867
3995
  }, { buttonClass: 'array', skipInlineCount: true });
@@ -3877,24 +4005,24 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
3877
4005
  selectedOption.querySelector("span").innerHTML = selectedOption.querySelector("span").innerHTML.replaceAll(selectedOption.querySelector("span").innerText, v);
3878
4006
  }
3879
4007
 
3880
- //Add dropdown options container
3881
- let list = document.createElement('ul');
4008
+ // Add dropdown options container
4009
+ let list = document.createElement( 'ul' );
3882
4010
  list.tabIndex = -1;
3883
4011
  list.className = "lexoptions";
3884
4012
  list.hidden = true;
3885
4013
 
3886
- list.addEventListener('focusout', function(e) {
4014
+ list.addEventListener( 'focusout', function( e ) {
3887
4015
  e.stopPropagation();
3888
4016
  e.stopImmediatePropagation();
3889
- if(e.relatedTarget === selectedOption.querySelector("button")) {
4017
+ if(e.relatedTarget === selectedOption.querySelector( 'button' )) {
3890
4018
  this.unfocus_event = true;
3891
- setTimeout(() => delete this.unfocus_event, 200);
3892
- } else if (e.relatedTarget && e.relatedTarget.tagName == "INPUT") {
4019
+ setTimeout( () => delete this.unfocus_event, 200 );
4020
+ } else if ( e.relatedTarget && e.relatedTarget.tagName == "INPUT" ) {
3893
4021
  return;
3894
- }else if (e.target.id == 'input-filter') {
4022
+ }else if ( e.target.id == 'input-filter' ) {
3895
4023
  return;
3896
4024
  }
3897
- this.toggleAttribute('hidden', true);
4025
+ this.toggleAttribute( 'hidden', true );
3898
4026
  });
3899
4027
 
3900
4028
  // Add filter options
@@ -4191,7 +4319,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
4191
4319
 
4192
4320
  // Add dropdown array button
4193
4321
 
4194
- const itemNameWidth = "3%";
4322
+ const itemNameWidth = "4%";
4195
4323
 
4196
4324
  var container = document.createElement('div');
4197
4325
  container.className = "lexarray";
@@ -4199,7 +4327,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
4199
4327
 
4200
4328
  this.queue( container );
4201
4329
 
4202
- const angle_down = `<a class='fa-solid fa-angle-down' style='float:right; margin-right: 6px;'></a>`;
4330
+ const angle_down = `<a class='fa-solid fa-angle-down' style='float:right; margin-right: 3px;'></a>`;
4203
4331
 
4204
4332
  let buttonName = "Array (size " + values.length + ")";
4205
4333
  buttonName += angle_down;
@@ -4267,7 +4395,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
4267
4395
  }
4268
4396
 
4269
4397
  buttonName = "Add item";
4270
- buttonName += "<a class='fa-solid fa-plus' style='float:right; margin-right: 6px; margin-top: 2px;'></a>";
4398
+ buttonName += "<a class='fa-solid fa-plus' style='float:right; margin-right: 3px; margin-top: 2px;'></a>";
4271
4399
  this.addButton(null, buttonName, (v, event) => {
4272
4400
  values.push( "" );
4273
4401
  updateItems();
@@ -4786,7 +4914,10 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
4786
4914
  doc.addEventListener("mouseup",inner_mouseup);
4787
4915
  lastY = e.pageY;
4788
4916
  document.body.classList.add('nocursor');
4917
+ document.body.classList.add('noevents');
4789
4918
  drag_icon.classList.remove('hidden');
4919
+ e.stopImmediatePropagation();
4920
+ e.stopPropagation();
4790
4921
  }
4791
4922
 
4792
4923
  function inner_mousemove(e) {
@@ -4810,6 +4941,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
4810
4941
  doc.removeEventListener("mousemove",inner_mousemove);
4811
4942
  doc.removeEventListener("mouseup",inner_mouseup);
4812
4943
  document.body.classList.remove('nocursor');
4944
+ document.body.classList.remove('noevents');
4813
4945
  drag_icon.classList.add('hidden');
4814
4946
  }
4815
4947
 
@@ -4956,7 +5088,10 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
4956
5088
  doc.addEventListener("mouseup",inner_mouseup);
4957
5089
  lastY = e.pageY;
4958
5090
  document.body.classList.add('nocursor');
5091
+ document.body.classList.add('noevents');
4959
5092
  drag_icon.classList.remove('hidden');
5093
+ e.stopImmediatePropagation();
5094
+ e.stopPropagation();
4960
5095
  }
4961
5096
 
4962
5097
  function inner_mousemove(e) {
@@ -4988,6 +5123,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
4988
5123
  doc.removeEventListener("mousemove",inner_mousemove);
4989
5124
  doc.removeEventListener("mouseup",inner_mouseup);
4990
5125
  document.body.classList.remove('nocursor');
5126
+ document.body.classList.remove('noevents');
4991
5127
  drag_icon.classList.add('hidden');
4992
5128
  }
4993
5129
 
@@ -5140,11 +5276,11 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5140
5276
 
5141
5277
  addFile( name, callback, options = { } ) {
5142
5278
 
5143
- if(!name) {
5144
- throw("Set Widget Name!");
5279
+ if( !name ) {
5280
+ throw( "Set Widget Name!" );
5145
5281
  }
5146
5282
 
5147
- let widget = this.create_widget(name, Widget.FILE, options);
5283
+ let widget = this.create_widget( name, Widget.FILE, options );
5148
5284
  let element = widget.domEl;
5149
5285
 
5150
5286
  let local = options.local ?? true;
@@ -5152,31 +5288,36 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5152
5288
  let read = options.read ?? true;
5153
5289
 
5154
5290
  // Create hidden input
5155
- let input = document.createElement('input');
5291
+ let input = document.createElement( 'input' );
5156
5292
  input.style.width = "calc( 100% - " + LX.DEFAULT_NAME_WIDTH + " - 10%)";
5157
5293
  input.type = 'file';
5158
- if(options.placeholder)
5294
+
5295
+ if( options.placeholder )
5159
5296
  input.placeholder = options.placeholder;
5160
5297
 
5161
- input.addEventListener('change', function(e) {
5298
+ input.addEventListener( 'change', function( e ) {
5299
+
5162
5300
  const files = e.target.files;
5163
5301
  if( !files.length ) return;
5164
- if(read)
5302
+ if( read )
5165
5303
  {
5304
+ if( options.onBeforeRead )
5305
+ options.onBeforeRead();
5306
+
5166
5307
  const reader = new FileReader();
5167
5308
 
5168
- if(type === 'text') reader.readAsText(files[0]);
5169
- else if(type === 'buffer') reader.readAsArrayBuffer(files[0]);
5170
- else if(type === 'bin') reader.readAsBinaryString(files[0]);
5171
- else if(type === 'url') reader.readAsDataURL(files[0]);
5309
+ if( type === 'text' ) reader.readAsText( files[ 0 ] );
5310
+ else if( type === 'buffer' ) reader.readAsArrayBuffer( files[ 0 ] );
5311
+ else if( type === 'bin' ) reader.readAsBinaryString( files[ 0 ] );
5312
+ else if( type === 'url' ) reader.readAsDataURL( files[ 0 ] );
5172
5313
 
5173
- reader.onload = (e) => { callback.call( this, e.target.result, files[0] ) } ;
5314
+ reader.onload = e => { callback.call( this, e.target.result, files[ 0 ] ) } ;
5174
5315
  }
5175
- else callback(files[0]);
5176
-
5316
+ else
5317
+ callback( files[ 0 ] );
5177
5318
  });
5178
5319
 
5179
- element.appendChild(input);
5320
+ element.appendChild( input );
5180
5321
 
5181
5322
  this.queue( element );
5182
5323
 
@@ -5184,9 +5325,9 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5184
5325
  {
5185
5326
  this.addButton(null, "<a style='margin-top: 0px;' class='fa-solid fa-gear'></a>", () => {
5186
5327
 
5187
- new Dialog("Load Settings", p => {
5188
- p.addDropdown("Type", ['text', 'buffer', 'bin', 'url'], type, v => { type = v } );
5189
- p.addButton(null, "Reload", v => { input.dispatchEvent( new Event('change') ) } );
5328
+ new Dialog( "Load Settings", p => {
5329
+ p.addDropdown( "Type", [ 'text', 'buffer', 'bin', 'url' ], type, v => { type = v } );
5330
+ p.addButton( null, "Reload", v => { input.dispatchEvent( new Event( 'change' ) ) } );
5190
5331
  });
5191
5332
 
5192
5333
  }, { className: "micro", skipInlineCount: true });
@@ -5717,8 +5858,8 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5717
5858
  this.root = root;
5718
5859
  this.title = titleDiv;
5719
5860
 
5720
- if(draggable)
5721
- makeDraggable( root, 'lexdialogtitle' );
5861
+ if( draggable )
5862
+ makeDraggable( root, { targetClass: 'lexdialogtitle' } );
5722
5863
 
5723
5864
  // Process position and size
5724
5865
  if(size.length && typeof(size[0]) != "string")
@@ -5740,6 +5881,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5740
5881
  }
5741
5882
 
5742
5883
  destroy() {
5884
+
5743
5885
  this.root.remove();
5744
5886
  }
5745
5887
 
@@ -5754,6 +5896,14 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5754
5896
  this.root.style.left = x + "px";
5755
5897
  this.root.style.top = y + "px";
5756
5898
  }
5899
+
5900
+ setTitle( title ) {
5901
+
5902
+ const titleDOM = this.root.querySelector( '.lexdialogtitle' );
5903
+ if( !titleDOM )
5904
+ return;
5905
+ titleDOM.innerText = title;
5906
+ }
5757
5907
  }
5758
5908
 
5759
5909
  LX.Dialog = Dialog;
@@ -5783,8 +5933,10 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5783
5933
 
5784
5934
  // Custom
5785
5935
  this.root.classList.add( "pocket" );
5786
- this.root.style.left = "calc(100% - " + (this.root.offsetWidth + 6) + "px)";
5787
- this.root.style.top = "0px";
5936
+ if( !options.position ) {
5937
+ this.root.style.left = "calc(100% - " + (this.root.offsetWidth + 6) + "px)";
5938
+ this.root.style.top = "0px";
5939
+ }
5788
5940
  this.panel.root.style.width = "calc( 100% - 12px )";
5789
5941
  this.panel.root.style.height = "calc( 100% - 40px )";
5790
5942
  this.dock_pos = PocketDialog.TOP;
@@ -5823,7 +5975,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5823
5975
  this.root.style.top = "calc(100% - " + (this.root.offsetHeight + 6) + "px)";
5824
5976
  break;
5825
5977
  case 'l':
5826
- this.root.style.left = "0px";
5978
+ this.root.style.left = options.position ? options.position[ 1 ] : "0px";
5827
5979
  break;
5828
5980
  }
5829
5981
  }
@@ -5928,7 +6080,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
5928
6080
  contextmenu.style.marginTop = 3.5 - c.offsetHeight + "px";
5929
6081
 
5930
6082
  // Set final width
5931
- contextmenu.style.width = contextmenu.offsetWidth + "px";
6083
+ // contextmenu.style.width = contextmenu.offsetWidth + "px";
5932
6084
  this._adjust_position( contextmenu, 6, true );
5933
6085
  }
5934
6086
 
@@ -6134,8 +6286,8 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
6134
6286
  element.style.minHeight = "50px";
6135
6287
  element.style.width = options.width || "100%";
6136
6288
 
6137
- element.bgcolor = options.bgcolor || "#15181c";
6138
- element.pointscolor = options.pointscolor || "#7b8ae2";
6289
+ element.bgcolor = options.bgcolor || LX.getThemeColor("global-dark-background");
6290
+ element.pointscolor = options.pointscolor || LX.getThemeColor("global-selected-light");
6139
6291
  element.linecolor = options.linecolor || "#555";
6140
6292
 
6141
6293
  element.value = value || [];
@@ -7376,9 +7528,15 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
7376
7528
  configurable: true
7377
7529
  });
7378
7530
 
7379
- Element.prototype.insertChildAtIndex = function(child, index = Infinity) {
7380
- if (index >= this.children.length) this.appendChild(child);
7381
- else this.insertBefore(child, this.children[index]);
7531
+ Element.prototype.insertChildAtIndex = function( child, index = Infinity ) {
7532
+ if ( index >= this.children.length ) this.appendChild( child );
7533
+ else this.insertBefore( child, this.children[index] );
7534
+ }
7535
+
7536
+ Element.prototype.hasClass = function( list ) {
7537
+ list = [].concat( list );
7538
+ var r = list.filter( v => this.classList.contains( v ) );
7539
+ return !!r.length;
7382
7540
  }
7383
7541
 
7384
7542
  Element.prototype.getComputedSize = function() {
@@ -7394,7 +7552,7 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
7394
7552
  compareThreshold( v, p, n, t ) { return Math.abs(v - p) >= t || Math.abs(v - n) >= t },
7395
7553
  compareThresholdRange( v0, v1, t0, t1 ) { return v0 >= t0 && v0 <= t1 || v1 >= t0 && v1 <= t1 || v0 <= t0 && v1 >= t1},
7396
7554
  clamp (num, min, max) { return Math.min(Math.max(num, min), max) },
7397
-
7555
+ uidGenerator: simple_guidGenerator,
7398
7556
  getControlPoints( x0, y0, x1, y1, x2, y2 ,t ) {
7399
7557
 
7400
7558
  // x0,y0,x1,y1 are the coordinates of the end (knot) pts of this segment
@@ -7419,7 +7577,6 @@ console.warn( 'Script "build/lexgui.js" is depracated and will be removed soon.
7419
7577
 
7420
7578
  return [p1x,p1y,p2x,p2y]
7421
7579
  },
7422
-
7423
7580
  drawSpline( ctx, pts, t ) {
7424
7581
 
7425
7582
  ctx.save();