lexgui 0.7.5 → 0.7.7

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.
@@ -193,7 +193,6 @@ class Timeline {
193
193
  this.setTime(value);
194
194
  }, {
195
195
  units: "s",
196
- signal: "@on_set_time_" + this.uniqueID,
197
196
  step: 0.01, min: 0, precision: 3,
198
197
  skipSlider: true,
199
198
  skipReset: true,
@@ -205,7 +204,6 @@ class Timeline {
205
204
  }, {
206
205
  units: "s",
207
206
  step: 0.01, min: 0,
208
- signal: "@on_set_duration_" + this.uniqueID,
209
207
  skipReset: true,
210
208
  nameWidth: "auto"
211
209
  });
@@ -261,7 +259,6 @@ class Timeline {
261
259
  */
262
260
  updateLeftPanel( ) {
263
261
 
264
- const scrollTop = this.trackTreesPanel ? this.trackTreesPanel.root.scrollTop : 0;
265
262
  this.leftPanel.clear();
266
263
 
267
264
  const panel = this.leftPanel;
@@ -326,7 +323,7 @@ class Timeline {
326
323
  }
327
324
  });
328
325
 
329
- this.trackTreesPanel.root.scrollTop = scrollTop;
326
+ this.trackTreesPanel.root.scrollTop = this.currentScrollInPixels;
330
327
 
331
328
  if( this.leftPanel.parent.root.classList.contains("hidden") || !this.root.parentElement ){
332
329
  return;
@@ -694,7 +691,7 @@ class Timeline {
694
691
  this.duration = this.animationClip.duration = v;
695
692
 
696
693
  if(updateHeader) {
697
- LX.emit( "@on_set_duration_" + this.uniqueID, + this.duration.toFixed(2)); // skipcallback = true
694
+ this.header.components["Duration"].set( +this.duration.toFixed(2), true ); // skipcallback = true
698
695
  }
699
696
 
700
697
  if( this.onSetDuration && !skipCallback )
@@ -703,7 +700,7 @@ class Timeline {
703
700
 
704
701
  setTime(time, skipCallback = false ){
705
702
  this.currentTime = Math.max(0,Math.min(time,this.duration));
706
- LX.emit( "@on_set_time_" + this.uniqueID, +this.currentTime.toFixed(2)); // skipcallback = true
703
+ this.header.components["Current Time"].set( +this.currentTime.toFixed(2), true ); // skipcallback = true
707
704
 
708
705
  if(this.onSetTime && !skipCallback)
709
706
  this.onSetTime(this.currentTime);
@@ -733,6 +730,41 @@ class Timeline {
733
730
  this.visualOriginTime += this.currentTime - this.xToTime(xCurrentTime);
734
731
  }
735
732
 
733
+ /**
734
+ * @method setScroll
735
+ * not delta from last state, but full scroll amount.
736
+ * @param {Number} scrollY either pixels or [0,1]
737
+ * @param {Bool} normalized if true, scrollY is in range[0,1] being 1 fully scrolled. Otherwised scrollY represents pixels
738
+ * @returns
739
+ */
740
+
741
+ setScroll( scrollY, normalized = true ){
742
+ if ( !this.trackTreesPanel ){
743
+ this.currentScroll = 0;
744
+ this.currentScrollInPixels = 0;
745
+ return;
746
+ }
747
+
748
+ const r = this.trackTreesPanel.root;
749
+ if (r.scrollHeight > r.clientHeight){
750
+ if ( normalized ){
751
+ this.currentScroll = scrollY;
752
+ this.currentScrollInPixels = scrollY * (r.scrollHeight - r.clientHeight);
753
+ }else{
754
+ this.currentScroll = scrollY / (r.scrollHeight - r.clientHeight);
755
+ this.currentScrollInPixels = scrollY;
756
+ }
757
+ }
758
+ else{
759
+ this.currentScroll = 0;
760
+ this.currentScrollInPixels = 0;
761
+ }
762
+
763
+ // automatically calls event.
764
+ this.trackTreesPanel.root.scrollTop = this.currentScrollInPixels;
765
+
766
+ }
767
+
736
768
  /**
737
769
  * @method processMouse
738
770
  * @param {*} e
@@ -1567,9 +1599,7 @@ class KeyFramesTimeline extends Timeline {
1567
1599
  */
1568
1600
  changeSelectedItems( itemsToAdd = null, itemsToRemove = null, skipCallback = false ) {
1569
1601
 
1570
- // TODO: maybe make this un-functions more general
1571
- this.deselectAllKeyFrames();
1572
- this.unHoverAll();
1602
+ this.deselectAllElements();
1573
1603
 
1574
1604
  const tracks = this.animationClip.tracks;
1575
1605
  const tracksPerGroup = this.animationClip.tracksPerGroup;
@@ -3219,9 +3249,7 @@ class ClipsTimeline extends Timeline {
3219
3249
  */
3220
3250
  changeSelectedItems( ) {
3221
3251
 
3222
- // TODO: maybe make this un-functions more general
3223
- this.deselectAllClips();
3224
- this.unHoverAll();
3252
+ this.deselectAllElements();
3225
3253
 
3226
3254
  this.selectedItems = this.animationClip.tracks.slice();
3227
3255
 
package/build/lexgui.css CHANGED
@@ -777,7 +777,6 @@ a svg, svg path {
777
777
  font-size: var(--global-font-size-lg);
778
778
  color: var(--global-text-secondary);
779
779
  cursor: pointer;
780
- margin-right: 0.4em;
781
780
  -webkit-user-select: none;
782
781
  -moz-user-select: none;
783
782
  -ms-user-select: none;
@@ -6337,7 +6336,11 @@ ul.lexassetscontent {
6337
6336
 
6338
6337
  .uppercase { text-transform: uppercase }
6339
6338
  .capitalize { text-transform: capitalize }
6339
+
6340
6340
  .decoration-none { text-decoration: none }
6341
+ .text-underline { text-decoration: underline }
6342
+
6343
+ .hover\:text-underline:hover { text-decoration: underline }
6341
6344
 
6342
6345
  /* Width / Height */
6343
6346
 
package/build/lexgui.js CHANGED
@@ -14,7 +14,7 @@ console.warn( 'Script _build/lexgui.js_ is depracated and will be removed soon.
14
14
  */
15
15
 
16
16
  const LX = {
17
- version: "0.7.5",
17
+ version: "0.7.7",
18
18
  ready: false,
19
19
  extensions: [], // Store extensions used
20
20
  signals: {}, // Events and triggers
@@ -543,16 +543,30 @@ async function init( options = { } )
543
543
  this.main_area = new LX.Area( { id: options.id ?? 'mainarea' } );
544
544
  }
545
545
 
546
- if( ( options.autoTheme ?? true ) )
546
+ // Initial or automatic changes don't force color scheme
547
+ // to be stored in localStorage
548
+
549
+ this._onChangeSystemTheme = function( event ) {
550
+ const storedcolorScheme = localStorage.getItem( "lxColorScheme" );
551
+ if( storedcolorScheme ) return;
552
+ LX.setTheme( event.matches ? "dark" : "light", false );
553
+ };
554
+
555
+ this._mqlPrefersDarkScheme = window.matchMedia ? window.matchMedia("(prefers-color-scheme: dark)") : null;
556
+
557
+ const storedcolorScheme = localStorage.getItem( "lxColorScheme" );
558
+ if( storedcolorScheme )
547
559
  {
548
- if( window.matchMedia && window.matchMedia( "(prefers-color-scheme: light)" ).matches )
560
+ LX.setTheme( storedcolorScheme );
561
+ }
562
+ else if( this._mqlPrefersDarkScheme && ( options.autoTheme ?? true ) )
563
+ {
564
+ if( window.matchMedia( "(prefers-color-scheme: light)" ).matches )
549
565
  {
550
- LX.setTheme( "light" );
566
+ LX.setTheme( "light", false );
551
567
  }
552
568
 
553
- window.matchMedia( "(prefers-color-scheme: dark)" ).addEventListener( "change", event => {
554
- LX.setTheme( event.matches ? "dark" : "light" );
555
- });
569
+ this._mqlPrefersDarkScheme.addEventListener( "change", this._onChangeSystemTheme );
556
570
  }
557
571
 
558
572
  return this.main_area;
@@ -2552,8 +2566,9 @@ class Tabs {
2552
2566
  });
2553
2567
 
2554
2568
  // Attach content
2555
- tabEl.childIndex = ( this.root.childElementCount - 1 );
2556
- this.root.appendChild( tabEl );
2569
+ const indexOffset = options.indexOffset ?? -1;
2570
+ tabEl.childIndex = ( this.root.childElementCount + indexOffset );
2571
+ this.root.insertChildAtIndex( tabEl, tabEl.childIndex + 1 );
2557
2572
  this.area.attach( contentEl );
2558
2573
  this.tabDOMs[ name ] = tabEl;
2559
2574
  this.tabs[ name ] = content;
@@ -3115,6 +3130,7 @@ class ContextMenu {
3115
3130
  }
3116
3131
  else if( (rect.top + rect.height) > window.innerHeight )
3117
3132
  {
3133
+ div.style.marginTop = "";
3118
3134
  top = (window.innerHeight - rect.height - margin);
3119
3135
  }
3120
3136
  }
@@ -4978,11 +4994,13 @@ LX.deepCopy = deepCopy;
4978
4994
  * @method setTheme
4979
4995
  * @description Set dark or light theme
4980
4996
  * @param {String} colorScheme Name of the scheme
4997
+ * @param {Boolean} storeLocal Store in localStorage
4981
4998
  */
4982
- function setTheme( colorScheme )
4999
+ function setTheme( colorScheme, storeLocal = true )
4983
5000
  {
4984
5001
  colorScheme = ( colorScheme == "light" ) ? "light" : "dark";
4985
5002
  document.documentElement.setAttribute( "data-theme", colorScheme );
5003
+ if( storeLocal ) localStorage.setItem( "lxColorScheme", colorScheme );
4986
5004
  LX.emit( "@on_new_color_scheme", colorScheme );
4987
5005
  }
4988
5006
 
@@ -5011,6 +5029,26 @@ function switchTheme()
5011
5029
 
5012
5030
  LX.switchTheme = switchTheme;
5013
5031
 
5032
+ /**
5033
+ * @method setSystemTheme
5034
+ * @description Sets back the system theme
5035
+ */
5036
+ function setSystemTheme()
5037
+ {
5038
+ const currentTheme = ( window.matchMedia && window.matchMedia( "(prefers-color-scheme: light)" ).matches ) ? "light" : "dark";
5039
+ setTheme( currentTheme );
5040
+ localStorage.removeItem( "lxColorScheme" );
5041
+
5042
+ // Reapply listener
5043
+ if( this._mqlPrefersDarkScheme )
5044
+ {
5045
+ this._mqlPrefersDarkScheme.removeEventListener( "change", this._onChangeSystemTheme );
5046
+ this._mqlPrefersDarkScheme.addEventListener( "change", this._onChangeSystemTheme );
5047
+ }
5048
+ }
5049
+
5050
+ LX.setSystemTheme = setSystemTheme;
5051
+
5014
5052
  /**
5015
5053
  * @method setThemeColor
5016
5054
  * @description Sets a new value for one of the main theme variables
@@ -8993,7 +9031,7 @@ class TextInput extends BaseComponent {
8993
9031
 
8994
9032
  this.valid = ( v ) => {
8995
9033
  v = v ?? this.value();
8996
- if( !v.length || wValue.pattern == "" ) return true;
9034
+ if( ( wValue.pattern ?? "" ) == "" ) return true;
8997
9035
  const regexp = new RegExp( wValue.pattern );
8998
9036
  return regexp.test( v );
8999
9037
  };
@@ -9732,19 +9770,21 @@ class Form extends BaseComponent {
9732
9770
 
9733
9771
  const primaryButton = new LX.Button( null, options.primaryActionName ?? "Submit", ( value, event ) => {
9734
9772
 
9773
+ const errors = [];
9774
+
9735
9775
  for( let entry in data )
9736
9776
  {
9737
9777
  let entryData = data[ entry ];
9738
9778
 
9739
9779
  if( !entryData.textComponent.valid() )
9740
9780
  {
9741
- return;
9781
+ errors.push( { type: "input_not_valid", entry } );
9742
9782
  }
9743
9783
  }
9744
9784
 
9745
9785
  if( callback )
9746
9786
  {
9747
- callback( container.formData, event );
9787
+ callback( container.formData, errors, event );
9748
9788
  }
9749
9789
  }, { width: "100%", minWidth: "0", buttonClass: options.primaryButtonClass ?? "contrast" } );
9750
9790
 
@@ -11183,7 +11223,7 @@ class RangeInput extends BaseComponent {
11183
11223
  container.appendChild( slider );
11184
11224
 
11185
11225
  slider.addEventListener( "input", e => {
11186
- this.set( isRangeValue ? [ e.target.valueAsNumber, ogValue[ 1 ] ] : e.target.valueAsNumber, false, e );
11226
+ this.set( isRangeValue ? [ Math.min(e.target.valueAsNumber, ogValue[ 1 ]), ogValue[ 1 ] ] : e.target.valueAsNumber, false, e );
11187
11227
  }, { passive: false });
11188
11228
 
11189
11229
  // If its a range value, we need to update the slider using the thumbs
@@ -11249,7 +11289,7 @@ class RangeInput extends BaseComponent {
11249
11289
  container.appendChild( maxSlider );
11250
11290
 
11251
11291
  maxSlider.addEventListener( "input", e => {
11252
- ogValue[ 1 ] = +e.target.valueAsNumber;
11292
+ ogValue[ 1 ] = Math.max(value, +e.target.valueAsNumber);
11253
11293
  this.set( [ value, ogValue[ 1 ] ], false, e );
11254
11294
  }, { passive: false });
11255
11295
  }
@@ -15949,8 +15989,7 @@ class Sidebar {
15949
15989
  return;
15950
15990
  }
15951
15991
 
15952
- const f = options.callback;
15953
- if( f ) f.call( this, key, item.value, e );
15992
+ let value = undefined;
15954
15993
 
15955
15994
  if( isCollapsable )
15956
15995
  {
@@ -15960,14 +15999,18 @@ class Sidebar {
15960
15999
  {
15961
16000
  item.value = !item.value;
15962
16001
  item.checkbox.set( item.value, true );
16002
+ value = item.value;
15963
16003
  }
15964
-
15965
- if( options.swap && !( e.target instanceof HTMLInputElement ) )
16004
+ else if( options.swap && !( e.target instanceof HTMLInputElement ) )
15966
16005
  {
15967
16006
  const swapInput = itemDom.querySelector( "input" );
15968
16007
  swapInput.checked = !swapInput.checked;
16008
+ value = swapInput.checked;
15969
16009
  }
15970
16010
 
16011
+ const f = options.callback;
16012
+ if( f ) f.call( this, key, value ?? entry, e );
16013
+
15971
16014
  // Manage selected
15972
16015
  if( this.displaySelected && !options.skipSelection )
15973
16016
  {
@@ -16385,7 +16428,7 @@ class AssetView {
16385
16428
  }
16386
16429
  else
16387
16430
  {
16388
- this.toolsPanel = area.addPanel({ className: 'flex flex-col overflow-hidden' });
16431
+ this.toolsPanel = area.addPanel({ className: 'flex flex-col overflow-hidden', height:"auto" });
16389
16432
  this.contentPanel = area.addPanel({ className: 'lexassetcontentpanel flex flex-col overflow-hidden' });
16390
16433
  }
16391
16434
 
@@ -16438,9 +16481,11 @@ class AssetView {
16438
16481
  this.toolsPanel.addText(null, textString, null, {
16439
16482
  inputClass: "nobg", disabled: true, signal: "@on_page_change", maxWidth: "16ch" }
16440
16483
  );
16484
+ this.toolsPanel.endLine();
16441
16485
 
16442
16486
  if( !this.skipBrowser )
16443
16487
  {
16488
+ this.toolsPanel.sameLine();
16444
16489
  this.toolsPanel.addComboButtons( null, [
16445
16490
  {
16446
16491
  value: "Left",
@@ -16475,9 +16520,9 @@ class AssetView {
16475
16520
  inputClass: "nobg", disabled: true, signal: "@on_folder_change",
16476
16521
  style: { fontWeight: "600", fontSize: "15px" }
16477
16522
  });
16478
- }
16479
16523
 
16480
- this.toolsPanel.endLine();
16524
+ this.toolsPanel.endLine();
16525
+ }
16481
16526
  };
16482
16527
 
16483
16528
  this.toolsPanel.refresh();