lexgui 0.4.1 → 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.
- package/build/components/audio.js +155 -154
- package/build/components/codeeditor.js +8 -6
- package/build/components/nodegraph.js +4 -3
- package/build/components/timeline.js +5 -2
- package/build/lexgui.css +552 -379
- package/build/lexgui.js +4457 -3593
- package/build/lexgui.min.css +7 -1
- package/build/lexgui.min.js +1 -1
- package/build/lexgui.module.js +4462 -3600
- package/build/lexgui.module.min.js +1 -1
- package/changelog.md +32 -2
- package/demo.js +1 -4
- package/examples/area_tabs.html +17 -2
- package/examples/dialogs.html +3 -3
- package/examples/timeline.html +1 -1
- package/package.json +28 -22
|
@@ -1,211 +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
|
-
* @
|
|
11
|
-
* @
|
|
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
|
-
|
|
22
|
-
let Widget = LX.Widget;
|
|
15
|
+
class Knob extends LX.Widget {
|
|
23
16
|
|
|
24
|
-
|
|
17
|
+
constructor( name, value, min, max, callback, options = {} ) {
|
|
25
18
|
|
|
26
|
-
|
|
19
|
+
if( value.constructor == Number )
|
|
20
|
+
{
|
|
21
|
+
value = LX.clamp( value, min, max );
|
|
22
|
+
value = options.precision ? LX.round( value, options.precision ) : value;
|
|
23
|
+
}
|
|
27
24
|
|
|
28
|
-
|
|
29
|
-
return innerKnobCircle.value;
|
|
30
|
-
};
|
|
31
|
-
widget.onSetValue = ( newValue, skipCallback ) => {
|
|
32
|
-
innerSetValue( newValue );
|
|
33
|
-
Panel._dispatch_event( innerKnobCircle, "change", skipCallback );
|
|
34
|
-
};
|
|
25
|
+
super( LX.Widget.KNOB, name, value, options );
|
|
35
26
|
|
|
36
|
-
|
|
27
|
+
this.onGetValue = () => {
|
|
28
|
+
return innerKnobCircle.value;
|
|
29
|
+
};
|
|
37
30
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
innerSetValue( innerKnobCircle.iValue );
|
|
43
|
-
Panel._dispatch_event( innerKnobCircle, "change" );
|
|
44
|
-
});
|
|
45
|
-
}
|
|
31
|
+
this.onSetValue = ( newValue, skipCallback ) => {
|
|
32
|
+
innerSetValue( newValue );
|
|
33
|
+
LX.Widget._dispatchEvent( innerKnobCircle, "change", skipCallback );
|
|
34
|
+
};
|
|
46
35
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
{
|
|
51
|
-
const range = (max - min) / options.snap;
|
|
52
|
-
for( let i = 0; i < ( options.snap + 1 ); ++i )
|
|
36
|
+
const snapEnabled = ( options.snap && options.snap.constructor == Number );
|
|
37
|
+
const ticks = [];
|
|
38
|
+
if( snapEnabled )
|
|
53
39
|
{
|
|
54
|
-
|
|
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
|
+
}
|
|
55
45
|
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
var container = document.createElement( 'div' );
|
|
59
|
-
container.className = "lexknob";
|
|
60
|
-
container.addClass( options.size );
|
|
61
|
-
container.addClass( snapEnabled ? "show-ticks" : null );
|
|
62
|
-
container.style.width = options.inputWidth || "calc( 100% - " + LX.DEFAULT_NAME_WIDTH + ")";
|
|
63
|
-
|
|
64
|
-
let knobCircle = document.createElement( 'div' );
|
|
65
|
-
knobCircle.className = "knobcircle";
|
|
66
|
-
if( snapEnabled )
|
|
67
|
-
{
|
|
68
|
-
knobCircle.style.setProperty( "--knob-snap-mark", ( 270 / options.snap ) + "deg" );
|
|
69
|
-
}
|
|
70
46
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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 + ")";
|
|
76
52
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
value = LX.clamp( value, min, max );
|
|
84
|
-
value = options.precision ? LX.round( value, options.precision ) : value;
|
|
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
|
-
|
|
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
|
+
}
|
|
88
78
|
|
|
89
|
-
|
|
90
|
-
let innerSetValue = function( v ) {
|
|
91
|
-
// Convert val between (-135 and 135)
|
|
92
|
-
const angle = LX.remapRange( v, innerKnobCircle.min, innerKnobCircle.max, -135.0, 135.0 );
|
|
79
|
+
const angle = LX.remapRange( value, min, max, -135.0, 135.0 );
|
|
93
80
|
innerKnobCircle.style.rotate = angle + 'deg';
|
|
94
|
-
innerKnobCircle.value = v;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const angle = LX.remapRange( value, min, max, -135.0, 135.0 );
|
|
98
|
-
innerKnobCircle.style.rotate = angle + 'deg';
|
|
99
|
-
|
|
100
|
-
if( options.disabled )
|
|
101
|
-
{
|
|
102
|
-
container.addClass( "disabled" );
|
|
103
|
-
}
|
|
104
81
|
|
|
105
|
-
|
|
82
|
+
if( options.disabled )
|
|
83
|
+
{
|
|
84
|
+
container.addClass( "disabled" );
|
|
85
|
+
}
|
|
106
86
|
|
|
107
|
-
|
|
87
|
+
innerKnobCircle.addEventListener( "change", e => {
|
|
108
88
|
|
|
109
|
-
|
|
89
|
+
const knob = e.target;
|
|
110
90
|
|
|
111
|
-
|
|
112
|
-
{
|
|
113
|
-
knob.value = ticks.reduce(( prev, curr ) => Math.abs( curr - knob.value ) < Math.abs( prev - knob.value ) ? curr : prev );
|
|
114
|
-
}
|
|
91
|
+
const skipCallback = e.detail;
|
|
115
92
|
|
|
116
|
-
|
|
117
|
-
|
|
93
|
+
if( mustSnap )
|
|
94
|
+
{
|
|
95
|
+
knob.value = ticks.reduce(( prev, curr ) => Math.abs( curr - knob.value ) < Math.abs( prev - knob.value ) ? curr : prev );
|
|
96
|
+
}
|
|
118
97
|
|
|
119
|
-
|
|
98
|
+
let val = knob.value = LX.clamp( knob.value, knob.min, knob.max );
|
|
99
|
+
val = options.precision ? LX.round( val, options.precision ) : val;
|
|
120
100
|
|
|
121
|
-
|
|
122
|
-
if( !skipCallback )
|
|
123
|
-
{
|
|
124
|
-
let btn = element.querySelector( ".lexwidgetname .lexicon" );
|
|
125
|
-
if( btn ) btn.style.display = val != innerKnobCircle.iValue ? "block": "none";
|
|
101
|
+
innerSetValue( val );
|
|
126
102
|
|
|
127
|
-
|
|
103
|
+
// Reset button (default value)
|
|
104
|
+
if( !skipCallback )
|
|
128
105
|
{
|
|
129
|
-
this.
|
|
130
|
-
|
|
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
|
+
}
|
|
131
114
|
}
|
|
132
|
-
}
|
|
133
115
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
// Add drag input
|
|
116
|
+
}, { passive: false });
|
|
137
117
|
|
|
138
|
-
|
|
118
|
+
// Add drag input
|
|
139
119
|
|
|
140
|
-
|
|
120
|
+
innerKnobCircle.addEventListener( "mousedown", inner_mousedown );
|
|
141
121
|
|
|
142
|
-
|
|
122
|
+
var that = this;
|
|
143
123
|
|
|
144
|
-
|
|
145
|
-
{
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
124
|
+
function inner_mousedown( e ) {
|
|
148
125
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
126
|
+
if( document.activeElement == innerKnobCircle || options.disabled )
|
|
127
|
+
{
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
153
130
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
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();
|
|
157
143
|
}
|
|
158
144
|
|
|
159
|
-
e
|
|
160
|
-
e.stopPropagation();
|
|
161
|
-
}
|
|
145
|
+
function inner_mousemove( e ) {
|
|
162
146
|
|
|
163
|
-
|
|
147
|
+
let dt = -e.movementY;
|
|
164
148
|
|
|
165
|
-
|
|
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
|
+
}
|
|
166
158
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
let mult = options.step ?? 1;
|
|
170
|
-
if(e.shiftKey) mult *= 10;
|
|
171
|
-
else if(e.altKey) mult *= 0.1;
|
|
172
|
-
let new_value = (innerKnobCircle.value - mult * dt);
|
|
173
|
-
innerKnobCircle.value = new_value;
|
|
174
|
-
Panel._dispatch_event( innerKnobCircle, 'change' );
|
|
159
|
+
e.stopPropagation();
|
|
160
|
+
e.preventDefault();
|
|
175
161
|
}
|
|
176
162
|
|
|
177
|
-
e
|
|
178
|
-
e.preventDefault();
|
|
179
|
-
}
|
|
163
|
+
function inner_mouseup( e ) {
|
|
180
164
|
|
|
181
|
-
|
|
165
|
+
var doc = that.root.ownerDocument;
|
|
166
|
+
doc.removeEventListener( 'mousemove', inner_mousemove );
|
|
167
|
+
doc.removeEventListener( 'mouseup', inner_mouseup );
|
|
168
|
+
document.body.classList.remove( 'noevents' );
|
|
182
169
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
170
|
+
// Snap if necessary
|
|
171
|
+
if( snapEnabled )
|
|
172
|
+
{
|
|
173
|
+
mustSnap = true;
|
|
174
|
+
LX.Widget._dispatchEvent( innerKnobCircle, 'change' );
|
|
175
|
+
}
|
|
187
176
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
Panel._dispatch_event( innerKnobCircle, 'change' );
|
|
177
|
+
if( document.pointerLockElement )
|
|
178
|
+
{
|
|
179
|
+
document.exitPointerLock();
|
|
180
|
+
}
|
|
193
181
|
}
|
|
194
182
|
|
|
195
|
-
|
|
183
|
+
container.appendChild( knobCircle );
|
|
184
|
+
this.root.appendChild( container );
|
|
185
|
+
|
|
186
|
+
// Remove branch padding and margins
|
|
187
|
+
if( !this.name )
|
|
196
188
|
{
|
|
197
|
-
|
|
189
|
+
this.root.className += " noname";
|
|
190
|
+
container.style.width = "100%";
|
|
198
191
|
}
|
|
199
192
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
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
|
+
*/
|
|
209
208
|
|
|
210
|
-
|
|
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 );
|
|
211
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
|
-
|
|
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
|
-
|
|
98
|
+
displaySelected: true,
|
|
99
|
+
headerIcon: "more",
|
|
99
100
|
headerTitle: "Create",
|
|
100
101
|
headerSubtitle: "Press to rename",
|
|
101
102
|
onHeaderPressed: () => this._showRenameGraphDialog(),
|
|
102
|
-
footerIcon: "
|
|
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.
|
|
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
|
|
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
|
-
|
|
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) => {
|