lexgui 0.1.29 → 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.
@@ -8,7 +8,7 @@
8
8
  */
9
9
 
10
10
  var LX = {
11
- version: "0.1.29",
11
+ version: "0.1.30",
12
12
  ready: false,
13
13
  components: [], // specific pre-build components
14
14
  signals: {} // events and triggers
@@ -418,33 +418,38 @@ function create_global_searchbar( root ) {
418
418
 
419
419
  /**
420
420
  * @method init
421
- * @param {*} options
421
+ * @param {Object} options
422
422
  * container: Root location for the gui (default is the document body)
423
+ * id: Id of the main area
423
424
  * skip_default_area: Skip creation of main area
424
425
  */
425
426
 
426
- function init(options = {})
427
+ function init( options = { } )
427
428
  {
428
- if(this.ready)
429
+ if( this.ready )
429
430
  return this.main_area;
430
431
 
431
- // LexGUI root
432
- var root = document.createElement("div");
432
+ // LexGUI root
433
+
434
+ var root = document.createElement( 'div' );
433
435
  root.id = "lexroot";
434
436
  root.tabIndex = -1;
435
437
 
436
- var modal = document.createElement("div");
438
+ var modal = document.createElement( 'div' );
437
439
  modal.id = "modal";
438
440
 
439
441
  this.modal = modal;
440
442
  this.root = root;
441
443
  this.container = document.body;
442
444
 
443
- this.modal.toggleAttribute('hidden', true);
444
- this.modal.toggle = function(force) { this.toggleAttribute('hidden', force); };
445
+ // this.modal.toggleAttribute( 'hidden', true );
446
+ // this.modal.toggle = function( force ) { this.toggleAttribute( 'hidden', force ); };
447
+
448
+ this.modal.classList.add( 'hiddenOpacity' );
449
+ this.modal.toggle = function( force ) { this.classList.toggle( 'hiddenOpacity', force ); };
445
450
 
446
- if(options.container)
447
- this.container = document.getElementById(options.container);
451
+ if( options.container )
452
+ this.container = document.getElementById( options.container );
448
453
 
449
454
  this.global_search = create_global_searchbar( this.container );
450
455
 
@@ -452,17 +457,17 @@ function init(options = {})
452
457
  this.container.appendChild( root );
453
458
 
454
459
  // Disable drag icon
455
- root.addEventListener("dragover", function(e) {
460
+ root.addEventListener( 'dragover', function( e ) {
456
461
  e.preventDefault();
457
462
  }, false );
458
463
 
459
464
  // CSS fontawesome
460
- var head = document.getElementsByTagName('HEAD')[0];
461
- var link = document.createElement('link');
465
+ var head = document.getElementsByTagName( 'HEAD' )[ 0 ];
466
+ var link = document.createElement( 'link' );
462
467
  link.rel = 'stylesheet';
463
468
  link.type = 'text/css';
464
- link.href = 'https://use.fontawesome.com/releases/v6.4.2/css/all.css';
465
- head.appendChild(link);
469
+ link.href = 'https://use.fontawesome.com/releases/v6.5.1/css/all.css';
470
+ head.appendChild( link );
466
471
 
467
472
  // Global vars
468
473
  this.DEFAULT_NAME_WIDTH = "30%";
@@ -470,10 +475,10 @@ function init(options = {})
470
475
  this.OPEN_CONTEXTMENU_ENTRY = 'click';
471
476
 
472
477
  this.ready = true;
473
- this.menubars = [];
478
+ this.menubars = [ ];
474
479
 
475
- if(!options.skip_default_area)
476
- this.main_area = new Area( {id: options.id ?? "mainarea"} );
480
+ if( !options.skip_default_area )
481
+ this.main_area = new Area( { id: options.id ?? 'mainarea' } );
477
482
 
478
483
  return this.main_area;
479
484
  }
@@ -1303,7 +1308,8 @@ class Area {
1303
1308
  selectable: b.selectable,
1304
1309
  selected: b.selected,
1305
1310
  icon: b.icon,
1306
- img: b.img
1311
+ img: b.img,
1312
+ className: b.class
1307
1313
  };
1308
1314
 
1309
1315
  if( group )
@@ -1513,7 +1519,7 @@ class Tabs {
1513
1519
 
1514
1520
  let container = document.createElement('div');
1515
1521
  container.className = "lexareatabs " + (options.fit ? "fit" : "row");
1516
-
1522
+
1517
1523
  const folding = options.folding ?? false;
1518
1524
  if(folding) container.classList.add("folding");
1519
1525
 
@@ -1565,6 +1571,29 @@ class Tabs {
1565
1571
  this.tabs = {};
1566
1572
  this.tabDOMs = {};
1567
1573
 
1574
+ if( options.fit )
1575
+ {
1576
+ // Create movable element
1577
+ let mEl = document.createElement('span');
1578
+ mEl.className = "lexareatab thumb";
1579
+ this.thumb = mEl;
1580
+ this.root.appendChild( mEl );
1581
+
1582
+ const resizeObserver = new ResizeObserver((entries) => {
1583
+ const tabEl = this.thumb.item;
1584
+ if( !tabEl ) return;
1585
+ var transition = this.thumb.style.transition;
1586
+ this.thumb.style.transition = "none";
1587
+ this.thumb.style.transform = "translate( " + ( tabEl.childIndex * tabEl.offsetWidth ) + "px )";
1588
+ this.thumb.style.width = ( tabEl.offsetWidth - 5 ) + "px";
1589
+ this.thumb.style.height = ( tabEl.offsetHeight - 6 ) + "px";
1590
+ flushCss( this.thumb );
1591
+ this.thumb.style.transition = transition;
1592
+ });
1593
+
1594
+ resizeObserver.observe( this.area.root );
1595
+ }
1596
+
1568
1597
  // debug
1569
1598
  if(folding)
1570
1599
  {
@@ -1662,6 +1691,14 @@ class Tabs {
1662
1691
 
1663
1692
  if(options.onSelect)
1664
1693
  options.onSelect(e, tabEl.dataset.name);
1694
+
1695
+ if( this.thumb )
1696
+ {
1697
+ this.thumb.style.transform = "translate( " + ( tabEl.childIndex * tabEl.offsetWidth ) + "px )";
1698
+ this.thumb.style.width = ( tabEl.offsetWidth - 5 ) + "px";
1699
+ this.thumb.style.height = ( tabEl.offsetHeight - 6 ) + "px";
1700
+ this.thumb.item = tabEl;
1701
+ }
1665
1702
  });
1666
1703
 
1667
1704
  tabEl.addEventListener("contextmenu", e => {
@@ -1690,13 +1727,26 @@ class Tabs {
1690
1727
  });
1691
1728
 
1692
1729
  // Attach content
1730
+ tabEl.childIndex = ( this.root.childElementCount - 1 );
1693
1731
  this.root.appendChild( tabEl );
1694
1732
  this.area.attach( contentEl );
1695
1733
  this.tabDOMs[ name ] = tabEl;
1696
1734
  this.tabs[ name ] = content;
1697
1735
 
1698
1736
  setTimeout( () => {
1699
- if( options.onCreate ) options.onCreate.call(this, this.area.root.getBoundingClientRect());
1737
+
1738
+ if( options.onCreate ) {
1739
+ options.onCreate.call(this, this.area.root.getBoundingClientRect());
1740
+ }
1741
+
1742
+ if( isSelected && this.thumb )
1743
+ {
1744
+ this.thumb.style.transform = "translate( " + ( tabEl.childIndex * tabEl.offsetWidth ) + "px )";
1745
+ this.thumb.style.width = ( tabEl.offsetWidth - 5 ) + "px";
1746
+ this.thumb.style.height = ( tabEl.offsetHeight - 6 ) + "px";
1747
+ this.thumb.item = tabEl;
1748
+ }
1749
+
1700
1750
  }, 10 );
1701
1751
  }
1702
1752
 
@@ -2191,6 +2241,7 @@ class SideBar {
2191
2241
  * @param {*} options:
2192
2242
  * callback: Function to call on each item
2193
2243
  * bottom: Bool to set item at the bottom as helper button (not selectable)
2244
+ * className: Add class to the entry DOM element
2194
2245
  */
2195
2246
 
2196
2247
  add( key, options = {} ) {
@@ -2207,14 +2258,14 @@ class SideBar {
2207
2258
  }
2208
2259
 
2209
2260
  let entry = document.createElement( 'div' );
2210
- entry.className = "lexsidebarentry";
2261
+ entry.className = "lexsidebarentry " + ( options.className ?? "" );
2211
2262
  entry.id = pKey;
2212
- entry.title = key;
2213
2263
 
2214
2264
  if( options.bottom )
2215
2265
  {
2216
2266
  this.footer.appendChild( entry );
2217
- }else
2267
+ }
2268
+ else
2218
2269
  {
2219
2270
  this.root.appendChild( entry );
2220
2271
  }
@@ -2226,6 +2277,11 @@ class SideBar {
2226
2277
  button.innerHTML = "<i class='"+ (options.icon ?? "") + "'></i>";
2227
2278
  entry.appendChild( button );
2228
2279
 
2280
+ let desc = document.createElement( 'span' );
2281
+ desc.className = 'lexsidebarentrydesc';
2282
+ desc.innerHTML = key;
2283
+ entry.appendChild( desc );
2284
+
2229
2285
  entry.addEventListener("click", () => {
2230
2286
 
2231
2287
  const f = options.callback;
@@ -2241,6 +2297,23 @@ class SideBar {
2241
2297
 
2242
2298
  this.items.push( { name: pKey, domEl: entry, callback: options.callback } );
2243
2299
  }
2300
+
2301
+ /**
2302
+ * @method select
2303
+ * @param {String} name Element name to select
2304
+ */
2305
+
2306
+ select( name ) {
2307
+
2308
+ let pKey = name.replace( /\s/g, '' ).replaceAll( '.', '' );
2309
+
2310
+ const entry = this.items.find( v => v.name === pKey );
2311
+
2312
+ if( !entry )
2313
+ return;
2314
+
2315
+ entry.domEl.click();
2316
+ }
2244
2317
  };
2245
2318
 
2246
2319
  LX.SideBar = SideBar;
@@ -3133,7 +3206,7 @@ class Panel {
3133
3206
 
3134
3207
  if( type != Widget.TITLE )
3135
3208
  {
3136
- element.style.width = "calc(100% - " + (this.current_branch || type == Widget.FILE ? 10 : 20) + "px)";
3209
+ element.style.width = "calc(100% - " + (this.current_branch || type == Widget.FILE || ( type == Widget.BUTTON && !name ) ? 10 : 20) + "px)";
3137
3210
  if( options.width ) {
3138
3211
  element.style.width = element.style.minWidth = options.width;
3139
3212
  }
@@ -4393,7 +4466,7 @@ class Panel {
4393
4466
  buttonName = "Add item";
4394
4467
  buttonName += "<a class='fa-solid fa-plus' style='float:right; margin-right: 3px; margin-top: 2px;'></a>";
4395
4468
  this.addButton(null, buttonName, (v, event) => {
4396
- values.push( "" );
4469
+ values.push( options.innerValues ? options.innerValues[ 0 ] : "" );
4397
4470
  updateItems();
4398
4471
  this._trigger( new IEvent(name, values, event), callback );
4399
4472
  }, { buttonClass: 'array' });
@@ -5267,6 +5340,7 @@ class Panel {
5267
5340
  * @param {Function} callback Callback function on change
5268
5341
  * @param {*} options:
5269
5342
  * local: Ask for local file
5343
+ * read: Return the file itself (False) or the contents (True)
5270
5344
  * type: type to read as [text (Default), buffer, bin, url]
5271
5345
  */
5272
5346
 
@@ -7549,6 +7623,13 @@ LX.UTILS = {
7549
7623
  compareThresholdRange( v0, v1, t0, t1 ) { return v0 >= t0 && v0 <= t1 || v1 >= t0 && v1 <= t1 || v0 <= t0 && v1 >= t1},
7550
7624
  clamp (num, min, max) { return Math.min(Math.max(num, min), max) },
7551
7625
  uidGenerator: simple_guidGenerator,
7626
+ deleteElement( el ) { if( el ) el.remove(); },
7627
+ flushCss(element) {
7628
+ // By reading the offsetHeight property, we are forcing
7629
+ // the browser to flush the pending CSS changes (which it
7630
+ // does to ensure the value obtained is accurate).
7631
+ element.offsetHeight;
7632
+ },
7552
7633
  getControlPoints( x0, y0, x1, y1, x2, y2, t ) {
7553
7634
 
7554
7635
  // x0,y0,x1,y1 are the coordinates of the end (knot) pts of this segment
package/changelog.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # lexgui.js changelog
2
2
 
3
+ ## 0.1.30
4
+
5
+ GraphEditor:
6
+ - Snap Multiplier (x1, x2, x3)
7
+ - Added Sidebar to change between graphs/functions.
8
+ - Start/Stop graph buttons in top buttons.
9
+ - Initial support for creating Graph Functions.
10
+ - Improved performance hiding nodes outside the viewport.
11
+ - Groundwork for graph/function renaming.
12
+ - Support "Autoconnect" nodes.
13
+ - Import/Export Groups + Move groups inside groups.
14
+
15
+ Support adding class to overlay buttons.
16
+ Add custom "title" on hover for Sidebar elements.
17
+ Added Sidebar.select method.
18
+ Improved select animation "fit" tabs.
19
+ Doc updates.
20
+ Minor bug fixes.
21
+
3
22
  ## 0.1.29
4
23
 
5
24
  GraphEditor:
@@ -2,7 +2,6 @@
2
2
  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
3
3
  <head>
4
4
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1">
6
5
  <title>LexGUI Code Editor Demo</title>
7
6
  <link rel="stylesheet" href="../build/lexgui.css">
8
7
  <link rel="icon" href="../images/icon.png">
@@ -21,16 +20,14 @@
21
20
  import { LX } from 'lexgui';
22
21
  import 'lexgui/components/codeeditor.js';
23
22
 
24
- window.LX = LX;
25
-
26
23
  // init library and get main area
27
24
  let area = LX.init();
28
25
 
29
- const file_explorer = false;
26
+ const file_explorer = true;
30
27
 
31
28
  if( !file_explorer )
32
29
  {
33
- var [leftArea, rightArea] = area.split({ sizes:["40%","60%"] });
30
+ var [leftArea, rightArea] = area.split({ sizes:["55%","45%"] });
34
31
 
35
32
  var canvas = document.createElement('canvas');
36
33
  canvas.id = "mycanvas";
@@ -55,14 +52,14 @@
55
52
  file_explorer: file_explorer
56
53
  });
57
54
 
58
- editor.loadFile( "../demo.js" );
59
- // editor.loadFile( "../data/json_sample.json" );
60
- // editor.loadFile( "../data/css_sample.css" );
61
- // editor.loadFile( "../data/cpp_sample.cpp" );
62
- // editor.loadFile( "../data/xml_sample.xml" );
63
- // editor.loadFile( "../data/python_sample.py" );
64
- // editor.loadFile( "../data/rust_sample.rs" );
65
- // editor.loadFile( "../localhost.bat" );
55
+ editor.loadFile( "../data/js_sample.js" );
56
+ editor.loadFile( "../data/json_sample.json" );
57
+ editor.loadFile( "../data/css_sample.css" );
58
+ editor.loadFile( "../data/cpp_sample.cpp" );
59
+ editor.loadFile( "../data/xml_sample.xml" );
60
+ editor.loadFile( "../data/python_sample.py" );
61
+ editor.loadFile( "../data/rust_sample.rs" );
62
+ editor.loadFile( "../localhost.bat" );
66
63
 
67
64
  if( !file_explorer )
68
65
  {
@@ -48,7 +48,7 @@
48
48
  'Asset View',
49
49
  'Code Editor',
50
50
  'Dialogs',
51
- 'Immediate UI',
51
+ // 'Immediate UI',
52
52
  'Node Graph',
53
53
  'Side Bar'
54
54
  ];
@@ -45,6 +45,7 @@
45
45
 
46
46
  } );
47
47
 
48
+ graph_editor.loadGraph( "../data/function_sample.json" );
48
49
  graph_editor.loadGraph( "../data/graph_sample.json" );
49
50
 
50
51
  function loop(dt) {
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lexgui",
3
- "version": "0.1.29",
3
+ "version": "0.1.30",
4
4
  "description": "JS library to create web graphical user interfaces",
5
5
  "type": "module",
6
6
  "main": "./build/lexgui.js",