lexgui 0.4.2 → 0.5.0

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,202 +1,212 @@
1
1
  import { LX } from 'lexgui';
2
2
 
3
- if(!LX) {
3
+ if( !LX )
4
+ {
4
5
  throw("lexgui.js missing!");
5
6
  }
6
7
 
7
8
  LX.components.push( 'Audio' );
8
9
 
9
10
  /**
10
- * @method addKnob
11
- * @param {String} name Widget name
12
- * @param {Number} value Knob value
13
- * @param {Number} min Min Knob value
14
- * @param {Number} max Max Knob value
15
- * @param {Function} callback Callback function on change
16
- * @param {*} options:
17
- * minLabel (String): Label to show as min value
18
- * maxLabel (String): Label to show as max value
11
+ * @class Knob
12
+ * @description Knob Widget
19
13
  */
20
14
 
21
- let Panel = LX.Panel;
22
- let Widget = LX.Widget;
15
+ class Knob extends LX.Widget {
23
16
 
24
- Panel.prototype.addKnob = function( name, value, min, max, callback, options = {} ) {
17
+ constructor( name, value, min, max, callback, options = {} ) {
25
18
 
26
- if( value.constructor == Number )
27
- {
28
- value = LX.clamp( value, min, max );
29
- value = options.precision ? LX.round( value, options.precision ) : value;
30
- }
19
+ if( value.constructor == Number )
20
+ {
21
+ value = LX.clamp( value, min, max );
22
+ value = options.precision ? LX.round( value, options.precision ) : value;
23
+ }
31
24
 
32
- let widget = this._createWidget( Widget.KNOB, name, value, options );
25
+ super( LX.Widget.KNOB, name, value, options );
33
26
 
34
- widget.onGetValue = () => {
35
- return innerKnobCircle.value;
36
- };
37
- widget.onSetValue = ( newValue, skipCallback ) => {
38
- innerSetValue( newValue );
39
- Panel._dispatch_event( innerKnobCircle, "change", skipCallback );
40
- };
27
+ this.onGetValue = () => {
28
+ return innerKnobCircle.value;
29
+ };
41
30
 
42
- let element = widget.domEl;
31
+ this.onSetValue = ( newValue, skipCallback ) => {
32
+ innerSetValue( newValue );
33
+ LX.Widget._dispatchEvent( innerKnobCircle, "change", skipCallback );
34
+ };
43
35
 
44
- const snapEnabled = ( options.snap && options.snap.constructor == Number );
45
- const ticks = [];
46
- if( snapEnabled )
47
- {
48
- const range = (max - min) / options.snap;
49
- for( let i = 0; i < ( options.snap + 1 ); ++i )
36
+ const snapEnabled = ( options.snap && options.snap.constructor == Number );
37
+ const ticks = [];
38
+ if( snapEnabled )
50
39
  {
51
- ticks.push( min + (i * range) );
40
+ const range = (max - min) / options.snap;
41
+ for( let i = 0; i < ( options.snap + 1 ); ++i )
42
+ {
43
+ ticks.push( min + (i * range) );
44
+ }
52
45
  }
53
- }
54
46
 
55
- var container = document.createElement( 'div' );
56
- container.className = "lexknob";
57
- container.addClass( options.size );
58
- container.addClass( snapEnabled ? "show-ticks" : null );
59
- container.style.width = options.inputWidth || "calc( 100% - " + LX.DEFAULT_NAME_WIDTH + ")";
60
-
61
- let knobCircle = document.createElement( 'div' );
62
- knobCircle.className = "knobcircle";
63
- if( snapEnabled )
64
- {
65
- knobCircle.style.setProperty( "--knob-snap-mark", ( 270 / options.snap ) + "deg" );
66
- }
47
+ var container = document.createElement( 'div' );
48
+ container.className = "lexknob";
49
+ container.addClass( options.size );
50
+ container.addClass( snapEnabled ? "show-ticks" : null );
51
+ container.style.width = options.inputWidth || "calc( 100% - " + LX.DEFAULT_NAME_WIDTH + ")";
67
52
 
68
- let innerKnobCircle = document.createElement( 'div' );
69
- innerKnobCircle.className = "innerknobcircle";
70
- innerKnobCircle.min = min;
71
- innerKnobCircle.max = max;
72
- knobCircle.appendChild( innerKnobCircle );
73
-
74
- let knobMarker = document.createElement( 'div' );
75
- knobMarker.className = "knobmarker";
76
- innerKnobCircle.appendChild( knobMarker );
77
- innerKnobCircle.value = innerKnobCircle.iValue = value;
78
-
79
- let mustSnap = false;
80
- let innerSetValue = function( v ) {
81
- // Convert val between (-135 and 135)
82
- const angle = LX.remapRange( v, innerKnobCircle.min, innerKnobCircle.max, -135.0, 135.0 );
83
- innerKnobCircle.style.rotate = angle + 'deg';
84
- innerKnobCircle.value = v;
85
- }
53
+ let knobCircle = document.createElement( 'div' );
54
+ knobCircle.className = "knobcircle";
55
+ if( snapEnabled )
56
+ {
57
+ knobCircle.style.setProperty( "--knob-snap-mark", ( 270 / options.snap ) + "deg" );
58
+ }
86
59
 
87
- const angle = LX.remapRange( value, min, max, -135.0, 135.0 );
88
- innerKnobCircle.style.rotate = angle + 'deg';
60
+ let innerKnobCircle = document.createElement( 'div' );
61
+ innerKnobCircle.className = "innerknobcircle";
62
+ innerKnobCircle.min = min;
63
+ innerKnobCircle.max = max;
64
+ knobCircle.appendChild( innerKnobCircle );
65
+
66
+ let knobMarker = document.createElement( 'div' );
67
+ knobMarker.className = "knobmarker";
68
+ innerKnobCircle.appendChild( knobMarker );
69
+ innerKnobCircle.value = innerKnobCircle.iValue = value;
70
+
71
+ let mustSnap = false;
72
+ let innerSetValue = function( v ) {
73
+ // Convert val between (-135 and 135)
74
+ const angle = LX.remapRange( v, innerKnobCircle.min, innerKnobCircle.max, -135.0, 135.0 );
75
+ innerKnobCircle.style.rotate = angle + 'deg';
76
+ innerKnobCircle.value = v;
77
+ }
89
78
 
90
- if( options.disabled )
91
- {
92
- container.addClass( "disabled" );
93
- }
79
+ const angle = LX.remapRange( value, min, max, -135.0, 135.0 );
80
+ innerKnobCircle.style.rotate = angle + 'deg';
94
81
 
95
- innerKnobCircle.addEventListener( "change", e => {
82
+ if( options.disabled )
83
+ {
84
+ container.addClass( "disabled" );
85
+ }
96
86
 
97
- const knob = e.target;
87
+ innerKnobCircle.addEventListener( "change", e => {
98
88
 
99
- const skipCallback = e.detail;
89
+ const knob = e.target;
100
90
 
101
- if( mustSnap )
102
- {
103
- knob.value = ticks.reduce(( prev, curr ) => Math.abs( curr - knob.value ) < Math.abs( prev - knob.value ) ? curr : prev );
104
- }
91
+ const skipCallback = e.detail;
105
92
 
106
- let val = knob.value = LX.clamp( knob.value, knob.min, knob.max );
107
- val = options.precision ? LX.round( val, options.precision ) : val;
93
+ if( mustSnap )
94
+ {
95
+ knob.value = ticks.reduce(( prev, curr ) => Math.abs( curr - knob.value ) < Math.abs( prev - knob.value ) ? curr : prev );
96
+ }
108
97
 
109
- innerSetValue( val );
98
+ let val = knob.value = LX.clamp( knob.value, knob.min, knob.max );
99
+ val = options.precision ? LX.round( val, options.precision ) : val;
110
100
 
111
- // Reset button (default value)
112
- if( !skipCallback )
113
- {
114
- let btn = element.querySelector( ".lexwidgetname .lexicon" );
115
- if( btn ) btn.style.display = val != innerKnobCircle.iValue ? "block": "none";
101
+ innerSetValue( val );
116
102
 
117
- if( !( snapEnabled && !mustSnap ) )
103
+ // Reset button (default value)
104
+ if( !skipCallback )
118
105
  {
119
- this._trigger( new LX.IEvent( name, val, e ), callback );
120
- mustSnap = false;
106
+ let btn = this.root.querySelector( ".lexwidgetname .lexicon" );
107
+ if( btn ) btn.style.display = val != innerKnobCircle.iValue ? "block": "none";
108
+
109
+ if( !( snapEnabled && !mustSnap ) )
110
+ {
111
+ this._trigger( new LX.IEvent( name, val, e ), callback );
112
+ mustSnap = false;
113
+ }
121
114
  }
122
- }
123
115
 
124
- }, { passive: false });
125
-
126
- // Add drag input
116
+ }, { passive: false });
127
117
 
128
- innerKnobCircle.addEventListener( "mousedown", inner_mousedown );
118
+ // Add drag input
129
119
 
130
- var that = this;
120
+ innerKnobCircle.addEventListener( "mousedown", inner_mousedown );
131
121
 
132
- function inner_mousedown( e ) {
122
+ var that = this;
133
123
 
134
- if( document.activeElement == innerKnobCircle || options.disabled )
135
- {
136
- return;
137
- }
124
+ function inner_mousedown( e ) {
138
125
 
139
- var doc = that.root.ownerDocument;
140
- doc.addEventListener("mousemove",inner_mousemove);
141
- doc.addEventListener("mouseup",inner_mouseup);
142
- document.body.classList.add('noevents');
126
+ if( document.activeElement == innerKnobCircle || options.disabled )
127
+ {
128
+ return;
129
+ }
143
130
 
144
- if( !document.pointerLockElement )
145
- {
146
- container.requestPointerLock();
131
+ var doc = that.root.ownerDocument;
132
+ doc.addEventListener("mousemove",inner_mousemove);
133
+ doc.addEventListener("mouseup",inner_mouseup);
134
+ document.body.classList.add('noevents');
135
+
136
+ if( !document.pointerLockElement )
137
+ {
138
+ container.requestPointerLock();
139
+ }
140
+
141
+ e.stopImmediatePropagation();
142
+ e.stopPropagation();
147
143
  }
148
144
 
149
- e.stopImmediatePropagation();
150
- e.stopPropagation();
151
- }
145
+ function inner_mousemove( e ) {
152
146
 
153
- function inner_mousemove( e ) {
147
+ let dt = -e.movementY;
154
148
 
155
- let dt = -e.movementY;
149
+ if ( dt != 0 )
150
+ {
151
+ let mult = options.step ?? 1;
152
+ if(e.shiftKey) mult *= 10;
153
+ else if(e.altKey) mult *= 0.1;
154
+ let new_value = (innerKnobCircle.value - mult * dt);
155
+ innerKnobCircle.value = new_value;
156
+ LX.Widget._dispatchEvent( innerKnobCircle, 'change' );
157
+ }
156
158
 
157
- if ( dt != 0 )
158
- {
159
- let mult = options.step ?? 1;
160
- if(e.shiftKey) mult *= 10;
161
- else if(e.altKey) mult *= 0.1;
162
- let new_value = (innerKnobCircle.value - mult * dt);
163
- innerKnobCircle.value = new_value;
164
- Panel._dispatch_event( innerKnobCircle, 'change' );
159
+ e.stopPropagation();
160
+ e.preventDefault();
165
161
  }
166
162
 
167
- e.stopPropagation();
168
- e.preventDefault();
169
- }
163
+ function inner_mouseup( e ) {
170
164
 
171
- function inner_mouseup( e ) {
165
+ var doc = that.root.ownerDocument;
166
+ doc.removeEventListener( 'mousemove', inner_mousemove );
167
+ doc.removeEventListener( 'mouseup', inner_mouseup );
168
+ document.body.classList.remove( 'noevents' );
172
169
 
173
- var doc = that.root.ownerDocument;
174
- doc.removeEventListener( 'mousemove', inner_mousemove );
175
- doc.removeEventListener( 'mouseup', inner_mouseup );
176
- document.body.classList.remove( 'noevents' );
170
+ // Snap if necessary
171
+ if( snapEnabled )
172
+ {
173
+ mustSnap = true;
174
+ LX.Widget._dispatchEvent( innerKnobCircle, 'change' );
175
+ }
177
176
 
178
- // Snap if necessary
179
- if( snapEnabled )
180
- {
181
- mustSnap = true;
182
- Panel._dispatch_event( innerKnobCircle, 'change' );
177
+ if( document.pointerLockElement )
178
+ {
179
+ document.exitPointerLock();
180
+ }
183
181
  }
184
182
 
185
- if( document.pointerLockElement )
183
+ container.appendChild( knobCircle );
184
+ this.root.appendChild( container );
185
+
186
+ // Remove branch padding and margins
187
+ if( !this.name )
186
188
  {
187
- document.exitPointerLock();
189
+ this.root.className += " noname";
190
+ container.style.width = "100%";
188
191
  }
189
192
  }
190
-
191
- container.appendChild( knobCircle );
192
- element.appendChild( container );
193
-
194
- // Remove branch padding and margins
195
- if( !widget.name )
196
- {
197
- element.className += " noname";
198
- container.style.width = "100%";
199
- }
193
+ }
194
+
195
+ LX.Knob = Knob;
196
+
197
+ /**
198
+ * @method addKnob
199
+ * @param {String} name Widget name
200
+ * @param {Number} value Knob value
201
+ * @param {Number} min Min Knob value
202
+ * @param {Number} max Max Knob value
203
+ * @param {Function} callback Callback function on change
204
+ * @param {*} options:
205
+ * minLabel (String): Label to show as min value
206
+ * maxLabel (String): Label to show as max value
207
+ */
200
208
 
201
- return widget;
209
+ LX.Panel.prototype.addKnob = function( name, value, min, max, callback, options = {} ) {
210
+ const widget = new Knob( name, value, min, max, callback, options );
211
+ return this._attachWidget( widget );
202
212
  }
@@ -302,8 +302,10 @@ class CodeEditor {
302
302
 
303
303
  this.addExplorerItem = function( item )
304
304
  {
305
- if( !this.explorer.data.children.find( (value, index) => value.id === item.id ) )
306
- this.explorer.data.children.push( item );
305
+ if( !this.explorer.innerTree.data.children.find( ( value, index ) => value.id === item.id ) )
306
+ {
307
+ this.explorer.innerTree.data.children.push( item );
308
+ }
307
309
  };
308
310
 
309
311
  explorerArea.attach( panel );
@@ -1240,7 +1242,7 @@ class CodeEditor {
1240
1242
 
1241
1243
  const ext = this.languages[ options.language ] ?. ext;
1242
1244
  this.addExplorerItem( { 'id': name, 'skipVisibility': true, 'icon': this._getFileIcon( name, ext ) } );
1243
- this.explorer.frefresh( name );
1245
+ this.explorer.innerTree.frefresh( name );
1244
1246
  }
1245
1247
  else
1246
1248
  {
@@ -1488,10 +1490,10 @@ class CodeEditor {
1488
1490
  // Update explorer icon
1489
1491
  if( this.explorer )
1490
1492
  {
1491
- const item = this.explorer.data.children.filter( (v) => v.id === this.code.tabName )[ 0 ];
1493
+ const item = this.explorer.innerTree.data.children.filter( (v) => v.id === this.code.tabName )[ 0 ];
1492
1494
  console.assert( item != undefined );
1493
1495
  item.icon = icon;
1494
- this.explorer.frefresh( this.code.tabName );
1496
+ this.explorer.innerTree.frefresh( this.code.tabName );
1495
1497
  }
1496
1498
  }
1497
1499
 
@@ -1720,7 +1722,7 @@ class CodeEditor {
1720
1722
  if( this.explorer && !isNewTabButton )
1721
1723
  {
1722
1724
  this.addExplorerItem( { 'id': name, 'skipVisibility': true, 'icon': tabIcon } );
1723
- this.explorer.frefresh( name );
1725
+ this.explorer.innerTree.frefresh( name );
1724
1726
  }
1725
1727
 
1726
1728
  this.tabs.add( name, code, {
@@ -95,11 +95,12 @@ class GraphEditor {
95
95
  this._sidebar = area.addSidebar( m => {
96
96
 
97
97
  }, {
98
- headerIcon: "More",
98
+ displaySelected: true,
99
+ headerIcon: "more",
99
100
  headerTitle: "Create",
100
101
  headerSubtitle: "Press to rename",
101
102
  onHeaderPressed: () => this._showRenameGraphDialog(),
102
- footerIcon: "Plus",
103
+ footerIcon: "plus",
103
104
  footerTitle: "Create",
104
105
  footerSubtitle: "Graph or Function",
105
106
  onFooterPressed: (e) => this._onSidebarCreate( e )
@@ -1204,7 +1205,7 @@ class GraphEditor {
1204
1205
  panel.addVector4( p.name, p.value, (v) => { p.value = v } );
1205
1206
  break;
1206
1207
  case 'select':
1207
- panel.addDropdown( p.name, p.options, p.value, (v) => { p.value = v } );
1208
+ panel.addSelect( p.name, p.options, p.value, (v) => { p.value = v } );
1208
1209
  break;
1209
1210
  case 'array':
1210
1211
  panel.addArray( p.name, p.value, (v) => {
@@ -258,7 +258,8 @@ class Timeline {
258
258
  let panel = this.leftPanel;
259
259
  panel.sameLine( 2 );
260
260
 
261
- let title = panel.addTitle( "Tracks" );
261
+ let titleWidget = panel.addTitle( "Tracks" );
262
+ let title = titleWidget.root;
262
263
 
263
264
  if( !this.disableNewTracks )
264
265
  {
@@ -2752,7 +2753,9 @@ class ClipsTimeline extends Timeline {
2752
2753
  let panel = this.leftPanel;
2753
2754
 
2754
2755
  panel.sameLine(2);
2755
- let title = panel.addTitle("Tracks");
2756
+
2757
+ let titleWidget = panel.addTitle("Tracks");
2758
+ let title = titleWidget.root;
2756
2759
  if(!this.disableNewTracks)
2757
2760
  {
2758
2761
  panel.addButton('', '<i class = "fa-solid fa-plus"></i>', (value, event) => {