lexgui 0.1.43 → 0.1.44

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.43",
11
+ version: "0.1.44",
12
12
  ready: false,
13
13
  components: [], // specific pre-build components
14
14
  signals: {} // events and triggers
@@ -70,8 +70,22 @@ LX.setThemeColor = setThemeColor;
70
70
 
71
71
  function getThemeColor( colorName )
72
72
  {
73
- var r = getComputedStyle( document.querySelector( ':root' ) );
74
- return r.getPropertyValue( '--' + colorName );
73
+ const r = getComputedStyle( document.querySelector( ':root' ) );
74
+ const value = r.getPropertyValue( '--' + colorName );
75
+
76
+ if( value.includes( "light-dark" ) && window.matchMedia )
77
+ {
78
+ if( window.matchMedia( "(prefers-color-scheme: light)" ).matches )
79
+ {
80
+ return value.substring( value.indexOf( '(' ) + 1, value.indexOf( ',' ) ).replace( /\s/g, '' );
81
+ }
82
+ else
83
+ {
84
+ return value.substring( value.indexOf( ',' ) + 1, value.indexOf( ')' ) ).replace( /\s/g, '' );
85
+ }
86
+ }
87
+
88
+ return value;
75
89
  }
76
90
 
77
91
  LX.getThemeColor = getThemeColor;
@@ -589,6 +603,10 @@ function init( options = { } )
589
603
  {
590
604
  this.container.appendChild( root );
591
605
  }
606
+ else
607
+ {
608
+ this.root = document.body;
609
+ }
592
610
 
593
611
  // Disable drag icon
594
612
  root.addEventListener( 'dragover', function( e ) {
@@ -621,6 +639,11 @@ function init( options = { } )
621
639
  this.main_area = new Area( { id: options.id ?? 'mainarea' } );
622
640
  }
623
641
 
642
+ window.matchMedia( "(prefers-color-scheme: dark)" ).addEventListener( "change", event => {
643
+ const newColorScheme = event.matches ? "dark" : "light";
644
+ LX.emit( "@on_new_color_scheme", newColorScheme );
645
+ });
646
+
624
647
  return this.main_area;
625
648
  }
626
649
 
@@ -750,6 +773,25 @@ function prompt( text, title, callback, options = {} )
750
773
 
751
774
  LX.prompt = prompt;
752
775
 
776
+ /**
777
+ * @method badge
778
+ * @param {String} text
779
+ * @param {String} className
780
+ * @param {*} options
781
+ * style: Style attributes to override
782
+ */
783
+
784
+ function badge( text, className, options = {} )
785
+ {
786
+ const container = document.createElement( "div" );
787
+ container.innerHTML = text;
788
+ container.className = "lexbadge " + ( className ?? "" );
789
+ Object.assign( container.style, options.style ?? {} );
790
+ return container.outerHTML;
791
+ }
792
+
793
+ LX.badge = badge;
794
+
753
795
  /*
754
796
  * Events and Signals
755
797
  */
@@ -837,7 +879,9 @@ function emit( signalName, value, options = {} )
837
879
  }
838
880
  else
839
881
  {
840
- obj[ signalName ].call( obj, value );
882
+ // This is a function callback!
883
+ const fn = obj;
884
+ fn( null, value );
841
885
  }
842
886
  }
843
887
  }
@@ -2631,27 +2675,29 @@ class Widget {
2631
2675
  static BUTTON = 3;
2632
2676
  static DROPDOWN = 4;
2633
2677
  static CHECKBOX = 5;
2634
- static COLOR = 6;
2635
- static NUMBER = 7;
2636
- static TITLE = 8;
2637
- static VECTOR = 9;
2638
- static TREE = 10;
2639
- static PROGRESS = 11;
2640
- static FILE = 12;
2641
- static LAYERS = 13;
2642
- static ARRAY = 14;
2643
- static LIST = 15;
2644
- static TAGS = 16;
2645
- static CURVE = 17;
2646
- static CARD = 18;
2647
- static IMAGE = 19;
2648
- static CONTENT = 20;
2649
- static CUSTOM = 21;
2650
- static SEPARATOR = 22;
2651
- static KNOB = 23;
2652
- static SIZE = 24;
2653
- static PAD = 25;
2654
- static FORM = 26;
2678
+ static TOGGLE = 6;
2679
+ static COLOR = 7;
2680
+ static NUMBER = 8;
2681
+ static TITLE = 9;
2682
+ static VECTOR = 10;
2683
+ static TREE = 11;
2684
+ static PROGRESS = 12;
2685
+ static FILE = 13;
2686
+ static LAYERS = 14;
2687
+ static ARRAY = 15;
2688
+ static LIST = 16;
2689
+ static TAGS = 17;
2690
+ static CURVE = 18;
2691
+ static CARD = 19;
2692
+ static IMAGE = 20;
2693
+ static CONTENT = 21;
2694
+ static CUSTOM = 22;
2695
+ static SEPARATOR = 23;
2696
+ static KNOB = 24;
2697
+ static SIZE = 25;
2698
+ static PAD = 26;
2699
+ static FORM = 27;
2700
+ static DIAL = 28;
2655
2701
 
2656
2702
  static NO_CONTEXT_TYPES = [
2657
2703
  Widget.BUTTON,
@@ -2724,6 +2770,7 @@ class Widget {
2724
2770
  case Widget.BUTTON: return "Button";
2725
2771
  case Widget.DROPDOWN: return "Dropdown";
2726
2772
  case Widget.CHECKBOX: return "Checkbox";
2773
+ case Widget.TOGGLE: return "Toggle";
2727
2774
  case Widget.COLOR: return "Color";
2728
2775
  case Widget.NUMBER: return "Number";
2729
2776
  case Widget.VECTOR: return "Vector";
@@ -2739,8 +2786,11 @@ class Widget {
2739
2786
  case Widget.SIZE: return "Size";
2740
2787
  case Widget.PAD: return "Pad";
2741
2788
  case Widget.FORM: return "Form";
2789
+ case Widget.DIAL: return "Dial";
2742
2790
  case Widget.CUSTOM: return this.customName;
2743
2791
  }
2792
+
2793
+ console.error( `Unknown Widget type: ${ this.type }` );
2744
2794
  }
2745
2795
 
2746
2796
  refresh() {
@@ -3913,41 +3963,50 @@ class Panel {
3913
3963
  /**
3914
3964
  * @method addTitle
3915
3965
  * @param {String} name Title name
3966
+ * @param {*} options:
3967
+ * link: Href in case title is an hyperlink
3968
+ * target: Target name of the iframe (if any)
3969
+ * icon: FA class of the icon (if any)
3970
+ * iconColor: Color of title icon (if any)
3971
+ * style: CSS to override
3916
3972
  */
3917
3973
 
3918
3974
  addTitle( name, options = {} ) {
3919
3975
 
3920
- if(!name) {
3921
- throw("Set Widget Name!");
3976
+ if( !name )
3977
+ {
3978
+ throw( "Can't create Title without text!" );
3922
3979
  }
3923
3980
 
3924
- let widget = this.create_widget(null, Widget.TITLE, options);
3981
+ let widget = this.create_widget( null, Widget.TITLE, options );
3925
3982
  let element = widget.domEl;
3926
3983
  element.className = "lextitle";
3927
3984
 
3928
- if(options.icon) {
3929
- let icon = document.createElement('a');
3985
+ if( options.icon )
3986
+ {
3987
+ let icon = document.createElement( 'a' );
3930
3988
  icon.className = options.icon;
3931
- icon.style.color = options.icon_color || "";
3932
- element.appendChild(icon);
3989
+ icon.style.color = options.iconColor || "";
3990
+ element.appendChild( icon );
3933
3991
  }
3934
3992
 
3935
- let text = document.createElement('span');
3993
+ let text = document.createElement( "span");
3936
3994
  text.innerText = name;
3937
- element.appendChild(text);
3995
+ element.appendChild( text );
3938
3996
 
3939
- Object.assign(element.style, options.style ?? {});
3997
+ Object.assign( element.style, options.style ?? {} );
3940
3998
 
3941
- if(options.link != undefined)
3999
+ if( options.link != undefined )
3942
4000
  {
3943
- let link_el = document.createElement('a');
3944
- link_el.innerText = name;
3945
- link_el.href = options.link;
3946
- link_el.target = options.target ?? "";
3947
- link_el.className = "lextitle link";
3948
- Object.assign(link_el.style, options.style ?? {});
3949
- element.replaceWith(link_el);
4001
+ let linkDom = document.createElement('a');
4002
+ linkDom.innerText = name;
4003
+ linkDom.href = options.link;
4004
+ linkDom.target = options.target ?? "";
4005
+ linkDom.className = "lextitle link";
4006
+ Object.assign( linkDom.style, options.style ?? {} );
4007
+ element.replaceWith( linkDom );
3950
4008
  }
4009
+
3951
4010
  return element;
3952
4011
  }
3953
4012
 
@@ -3996,6 +4055,11 @@ class Panel {
3996
4055
  container.style.width = options.inputWidth || "calc( 100% - " + LX.DEFAULT_NAME_WIDTH + " )";
3997
4056
  container.style.display = "flex";
3998
4057
 
4058
+ if( options.textClass )
4059
+ {
4060
+ container.classList.add( options.textClass );
4061
+ }
4062
+
3999
4063
  this.disabled = ( options.disabled || options.warning ) ?? ( options.url ? true : false );
4000
4064
  let wValue = null;
4001
4065
 
@@ -4464,20 +4528,33 @@ class Panel {
4464
4528
 
4465
4529
  for( let entry in data )
4466
4530
  {
4467
- const entryData = data[ entry ];
4468
- this.addText( entry, entryData.constructor == Object ? entryData.value : entryData, ( value ) => {
4531
+ let entryData = data[ entry ];
4532
+
4533
+ if( entryData.constructor != Object )
4534
+ {
4535
+ entryData = { };
4536
+ }
4537
+
4538
+ entryData.placeholder = entryData.placeholder ?? entry;
4539
+ entryData.width = "calc(100% - 10px)";
4540
+
4541
+ this.addLabel( entry, { textClass: "formlabel" } );
4542
+
4543
+ this.addText( null, entryData.constructor == Object ? entryData.value : entryData, ( value ) => {
4469
4544
  container.formData[ entry ] = value;
4470
4545
  }, entryData );
4471
4546
 
4472
4547
  container.formData[ entry ] = entryData.constructor == Object ? entryData.value : entryData;
4473
4548
  }
4474
4549
 
4550
+ this.addBlank( );
4551
+
4475
4552
  this.addButton( null, options.actionName ?? "Submit", ( value, event ) => {
4476
4553
  if( callback )
4477
4554
  {
4478
4555
  callback( container.formData, event );
4479
4556
  }
4480
- } );
4557
+ }, { buttonClass: "accept", width: "calc(100% - 10px)" } );
4481
4558
 
4482
4559
  this.clearQueue();
4483
4560
 
@@ -4493,16 +4570,32 @@ class Panel {
4493
4570
 
4494
4571
  /**
4495
4572
  * @method addContent
4496
- * @param {HTMLElement} element
4573
+ * @param {HTMLElement/String} element
4497
4574
  */
4498
4575
 
4499
4576
  addContent( element, options = {} ) {
4500
4577
 
4501
4578
  if( !element )
4502
- return;
4579
+ {
4580
+ return;
4581
+ }
4582
+
4583
+ if( element.constructor == String )
4584
+ {
4585
+ const tmp = document.createElement( "div" );
4586
+ tmp.innerHTML = element;
4587
+ if( tmp.childElementCount > 1 )
4588
+ {
4589
+ element = tmp;
4590
+ }
4591
+ else
4592
+ {
4593
+ element = tmp.firstElementChild;
4594
+ }
4595
+ }
4503
4596
 
4504
- let widget = this.create_widget(null, Widget.CONTENT, options);
4505
- widget.domEl.appendChild(element);
4597
+ let widget = this.create_widget( null, Widget.CONTENT, options );
4598
+ widget.domEl.appendChild( element );
4506
4599
  return widget;
4507
4600
  }
4508
4601
 
@@ -4607,7 +4700,7 @@ class Panel {
4607
4700
  const iString = String( i );
4608
4701
  maxWidth = Math.max( iString.length, maxWidth );
4609
4702
  }
4610
- return maxWidth * 9;
4703
+ return Math.max( maxWidth * 10, 80 );
4611
4704
  };
4612
4705
 
4613
4706
  let selectedOption = this.addButton( null, buttonName, ( value, event ) => {
@@ -4850,6 +4943,86 @@ class Panel {
4850
4943
  return widget;
4851
4944
  }
4852
4945
 
4946
+ /**
4947
+ * @method addDial
4948
+ * @param {String} name Widget name
4949
+ * @param {Array of Array} values Array of 2N Arrays of each value of the dial
4950
+ * @param {Function} callback Callback function on change
4951
+ * @param {*} options:
4952
+ * skipReset: Don't add the reset value button when value changes
4953
+ * bgColor: Widget background color
4954
+ * pointsColor: Curve points color
4955
+ * lineColor: Curve line color
4956
+ * noOverlap: Points do not overlap, replacing themselves if necessary
4957
+ * allowAddValues: Support adding values on click
4958
+ * smooth: Curve smoothness
4959
+ * moveOutAction: Clamp or delete points moved out of the curve (LX.CURVE_MOVEOUT_CLAMP, LX.CURVE_MOVEOUT_DELETE)
4960
+ */
4961
+
4962
+ addDial( name, values, callback, options = {} ) {
4963
+
4964
+ let that = this;
4965
+ let widget = this.create_widget(name, Widget.DIAL, options);
4966
+
4967
+ widget.onGetValue = () => {
4968
+ return JSON.parse(JSON.stringify(curveInstance.element.value));
4969
+ };
4970
+
4971
+ widget.onSetValue = ( newValue, skipCallback ) => {
4972
+ let btn = element.querySelector( ".lexwidgetname .lexicon" );
4973
+ if( btn ) btn.style.display = ( newValue != curveInstance.element.value ? "block" : "none" );
4974
+ curveInstance.element.value = JSON.parse( JSON.stringify( newValue ) );
4975
+ curveInstance.redraw();
4976
+ if( !skipCallback ) that._trigger( new IEvent( name, curveInstance.element.value, null ), callback );
4977
+ };
4978
+
4979
+ let element = widget.domEl;
4980
+ let defaultValues = JSON.parse( JSON.stringify( values ) );
4981
+
4982
+ // Add reset functionality
4983
+ if( widget.name && !(options.skipReset ?? false) )
4984
+ {
4985
+ Panel._add_reset_property(element.domName, function(e) {
4986
+ this.style.display = "none";
4987
+ curveInstance.element.value = JSON.parse( JSON.stringify( defaultValues ) );
4988
+ curveInstance.redraw();
4989
+ that._trigger( new IEvent( name, curveInstance.element.value, e ), callback );
4990
+ });
4991
+ }
4992
+
4993
+ // Add widget value
4994
+
4995
+ var container = document.createElement( 'div' );
4996
+ container.className = "lexcurve";
4997
+ container.style.width = widget.name ? "calc( 100% - " + LX.DEFAULT_NAME_WIDTH + ")" : '100%';
4998
+
4999
+ options.callback = (v, e) => {
5000
+ let btn = element.querySelector(".lexwidgetname .lexicon");
5001
+ if(btn) btn.style.display = (v != defaultValues ? "block" : "none");
5002
+ that._trigger( new IEvent(name, v, e), callback );
5003
+ };
5004
+
5005
+ options.name = name;
5006
+
5007
+ let curveInstance = new Dial( this, values, options );
5008
+ container.appendChild( curveInstance.element );
5009
+ element.appendChild( container );
5010
+
5011
+ // Resize
5012
+ widget.onresize = curveInstance.redraw.bind( curveInstance );
5013
+ widget.curveInstance = curveInstance;
5014
+
5015
+ doAsync(() => {
5016
+ curveInstance.element.style.height = curveInstance.element.offsetWidth + "px";
5017
+ curveInstance.canvas.width = curveInstance.element.offsetWidth;
5018
+ container.style.width = curveInstance.element.offsetWidth + "px";
5019
+ curveInstance.canvas.height = curveInstance.canvas.width;
5020
+ curveInstance.redraw();
5021
+ });
5022
+
5023
+ return widget;
5024
+ }
5025
+
4853
5026
  /**
4854
5027
  * @method addLayers
4855
5028
  * @param {String} name Widget name
@@ -5257,29 +5430,36 @@ class Panel {
5257
5430
  * @param {*} options:
5258
5431
  * disabled: Make the widget disabled [false]
5259
5432
  * suboptions: Callback to add widgets in case of TRUE value
5433
+ * className: Customize colors
5260
5434
  */
5261
5435
 
5262
5436
  addCheckbox( name, value, callback, options = {} ) {
5263
5437
 
5264
- if( !name ) {
5438
+ if( !name )
5439
+ {
5265
5440
  throw( "Set Widget Name!" );
5266
5441
  }
5267
5442
 
5268
5443
  let widget = this.create_widget( name, Widget.CHECKBOX, options );
5269
5444
 
5270
5445
  widget.onGetValue = () => {
5271
- return flag.value;
5446
+ return checkbox.checked;
5272
5447
  };
5448
+
5273
5449
  widget.onSetValue = ( newValue, skipCallback ) => {
5274
- if( flag.value !== newValue )
5275
- Panel._dispatch_event( toggle, "click", skipCallback );
5450
+ if( checkbox.checked !== newValue )
5451
+ {
5452
+ checkbox.checked = newValue;
5453
+ Panel._dispatch_event( checkbox, "change", skipCallback );
5454
+ }
5276
5455
  };
5277
5456
 
5278
5457
  let element = widget.domEl;
5279
5458
 
5280
5459
  // Add reset functionality
5281
5460
  Panel._add_reset_property( element.domName, function() {
5282
- Panel._dispatch_event( toggle, "click" );
5461
+ checkbox.checked = !checkbox.checked;
5462
+ Panel._dispatch_event( checkbox, "change" );
5283
5463
  });
5284
5464
 
5285
5465
  // Add widget value
@@ -5287,55 +5467,132 @@ class Panel {
5287
5467
  var container = document.createElement('div');
5288
5468
  container.className = "lexcheckboxcont";
5289
5469
 
5290
- let toggle = document.createElement('span');
5291
- toggle.className = "lexcheckbox";
5470
+ let checkbox = document.createElement('input');
5471
+ checkbox.type = "checkbox";
5472
+ checkbox.className = "lexcheckbox " + ( options.className ?? "" );
5473
+ checkbox.checked = value;
5474
+ checkbox.iValue = value;
5475
+ checkbox.disabled = options.disabled ?? false;
5292
5476
 
5293
- let flag = document.createElement('span');
5294
- flag.value = flag.iValue = value || false;
5295
- flag.className = "checkbox " + (flag.value ? "on" : "");
5296
- flag.id = "checkbox"+simple_guidGenerator();
5297
- flag.innerHTML = "<a class='fa-solid fa-check' style='display: " + (flag.value ? "block" : "none") + "'></a>";
5477
+ let valueName = document.createElement( 'span' );
5478
+ valueName.className = "checkboxtext";
5479
+ valueName.innerHTML = "On";
5298
5480
 
5299
- if( options.disabled ) {
5300
- flag.disabled = true;
5301
- toggle.className += " disabled";
5481
+ container.appendChild( checkbox );
5482
+ container.appendChild( valueName );
5483
+
5484
+ checkbox.addEventListener( "change" , e => {
5485
+
5486
+ const skipCallback = ( e.detail?.constructor == Number ? null : e.detail );
5487
+
5488
+ // Reset button (default value)
5489
+ if( !skipCallback )
5490
+ {
5491
+ let btn = element.querySelector( ".lexwidgetname .lexicon" );
5492
+ if( btn ) btn.style.display = checkbox.checked != checkbox.iValue ? "block": "none";
5493
+ }
5494
+
5495
+ // Open suboptions
5496
+ let submenu = element.querySelector( ".lexcheckboxsubmenu" );
5497
+ if( submenu ) submenu.toggleAttribute( 'hidden', !checkbox.checked );
5498
+
5499
+ if( !skipCallback ) this._trigger( new IEvent( name, checkbox.checked, e ), callback );
5500
+ });
5501
+
5502
+ element.appendChild( container );
5503
+
5504
+ if( options.suboptions )
5505
+ {
5506
+ element.style.flexWrap = "wrap";
5507
+ let suboptions = document.createElement('div');
5508
+ suboptions.className = "lexcheckboxsubmenu";
5509
+ suboptions.toggleAttribute( 'hidden', !checkbox.checked );
5510
+
5511
+ this.queue( suboptions );
5512
+ options.suboptions.call(this, this);
5513
+ this.clearQueue();
5514
+
5515
+ element.appendChild( suboptions );
5302
5516
  }
5303
5517
 
5304
- toggle.appendChild( flag );
5518
+ return widget;
5519
+ }
5520
+
5521
+ /**
5522
+ * @method addToggle
5523
+ * @param {String} name Widget name
5524
+ * @param {Boolean} value Value of the checkbox
5525
+ * @param {Function} callback Callback function on change
5526
+ * @param {*} options:
5527
+ * disabled: Make the widget disabled [false]
5528
+ * suboptions: Callback to add widgets in case of TRUE value
5529
+ * className: Customize colors
5530
+ */
5305
5531
 
5306
- let value_name = document.createElement( 'span' );
5307
- value_name.id = "checkboxtext";
5308
- value_name.innerHTML = "On";
5532
+ addToggle( name, value, callback, options = {} ) {
5309
5533
 
5310
- container.appendChild( toggle );
5311
- container.appendChild( value_name );
5534
+ if( !name )
5535
+ {
5536
+ throw( "Set Widget Name!" );
5537
+ }
5312
5538
 
5313
- toggle.addEventListener( "click" , e => {
5539
+ let widget = this.create_widget( name, Widget.TOGGLE, options );
5314
5540
 
5315
- let flag = toggle.querySelector( ".checkbox" );
5316
- if( flag.disabled )
5317
- return;
5541
+ widget.onGetValue = () => {
5542
+ return toggle.checked;
5543
+ };
5544
+
5545
+ widget.onSetValue = ( newValue, skipCallback ) => {
5546
+ if( toggle.checked !== newValue )
5547
+ {
5548
+ toggle.checked = newValue;
5549
+ Panel._dispatch_event( toggle, "change", skipCallback );
5550
+ }
5551
+ };
5552
+
5553
+ let element = widget.domEl;
5554
+
5555
+ // Add reset functionality
5556
+ Panel._add_reset_property( element.domName, function() {
5557
+ toggle.checked = !toggle.checked;
5558
+ Panel._dispatch_event( toggle, "change" );
5559
+ });
5560
+
5561
+ // Add widget value
5562
+
5563
+ var container = document.createElement('div');
5564
+ container.className = "lextogglecont";
5565
+
5566
+ let toggle = document.createElement('input');
5567
+ toggle.type = "checkbox";
5568
+ toggle.className = "lextoggle " + ( options.className ?? "" );
5569
+ toggle.checked = value;
5570
+ toggle.iValue = value;
5571
+ toggle.disabled = options.disabled ?? false;
5318
5572
 
5319
- const skipCallback = ( e.detail.constructor == Number ? null : e.detail );
5573
+ let valueName = document.createElement( 'span' );
5574
+ valueName.className = "toggletext";
5575
+ valueName.innerHTML = "On";
5576
+
5577
+ container.appendChild( toggle );
5578
+ container.appendChild( valueName );
5320
5579
 
5321
- let check = toggle.querySelector( ".checkbox a" );
5580
+ toggle.addEventListener( "change" , e => {
5322
5581
 
5323
- flag.value = !flag.value;
5324
- flag.className = "checkbox " + ( flag.value ? "on" : "" );
5325
- check.style.display = flag.value ? "block" : "none";
5582
+ const skipCallback = ( e.detail?.constructor == Number ? null : e.detail );
5326
5583
 
5327
5584
  // Reset button (default value)
5328
5585
  if( !skipCallback )
5329
5586
  {
5330
5587
  let btn = element.querySelector( ".lexwidgetname .lexicon" );
5331
- if( btn ) btn.style.display = flag.value != flag.iValue ? "block": "none";
5588
+ if( btn ) btn.style.display = toggle.checked != toggle.iValue ? "block": "none";
5332
5589
  }
5333
5590
 
5334
5591
  // Open suboptions
5335
- let submenu = element.querySelector( ".lexcheckboxsubmenu" );
5336
- if( submenu ) submenu.toggleAttribute( 'hidden', !flag.value );
5592
+ let submenu = element.querySelector( ".lextogglesubmenu" );
5593
+ if( submenu ) submenu.toggleAttribute( 'hidden', !toggle.checked );
5337
5594
 
5338
- if( !skipCallback ) this._trigger( new IEvent( name, flag.value, e ), callback );
5595
+ if( !skipCallback ) this._trigger( new IEvent( name, toggle.checked, e ), callback );
5339
5596
  });
5340
5597
 
5341
5598
  element.appendChild( container );
@@ -5344,14 +5601,14 @@ class Panel {
5344
5601
  {
5345
5602
  element.style.flexWrap = "wrap";
5346
5603
  let suboptions = document.createElement('div');
5347
- suboptions.className = "lexcheckboxsubmenu";
5348
- suboptions.toggleAttribute('hidden', !flag.value);
5604
+ suboptions.className = "lextogglesubmenu";
5605
+ suboptions.toggleAttribute( 'hidden', !toggle.checked );
5349
5606
 
5350
5607
  this.queue( suboptions );
5351
5608
  options.suboptions.call(this, this);
5352
5609
  this.clearQueue();
5353
5610
 
5354
- element.appendChild(suboptions);
5611
+ element.appendChild( suboptions );
5355
5612
  }
5356
5613
 
5357
5614
  return widget;
@@ -5580,7 +5837,14 @@ class Panel {
5580
5837
  };
5581
5838
  }
5582
5839
 
5583
- // Add wheel input
5840
+ vecinput.addEventListener( "input", function( e ) {
5841
+ let new_value = +this.valueAsNumber;
5842
+ vecinput.value = round( new_value, options.precision );
5843
+ if( options.units )
5844
+ {
5845
+ vecinput.unitSpan.style.left = measureRealWidth( vecinput.value ) + "px";
5846
+ }
5847
+ }, false );
5584
5848
 
5585
5849
  vecinput.addEventListener( "wheel", function( e ) {
5586
5850
  e.preventDefault();
@@ -6276,8 +6540,11 @@ class Panel {
6276
6540
  };
6277
6541
  widget.onSetValue = ( newValue, skipCallback ) => {
6278
6542
  element.querySelector("meter").value = newValue;
6543
+ _updateColor();
6279
6544
  if( element.querySelector("span") )
6545
+ {
6280
6546
  element.querySelector("span").innerText = newValue;
6547
+ }
6281
6548
  };
6282
6549
 
6283
6550
  let element = widget.domEl;
@@ -6294,14 +6561,26 @@ class Panel {
6294
6561
  progress.step = "any";
6295
6562
  progress.min = options.min ?? 0;
6296
6563
  progress.max = options.max ?? 1;
6564
+ progress.low = options.low ?? progress.low;
6565
+ progress.high = options.high ?? progress.high;
6566
+ progress.optimum = options.optimum ?? progress.optimum;
6297
6567
  progress.value = value;
6298
6568
 
6299
- if( options.low )
6300
- progress.low = options.low;
6301
- if( options.high )
6302
- progress.high = options.high;
6303
- if( options.optimum )
6304
- progress.optimum = options.optimum;
6569
+ const _updateColor = () => {
6570
+
6571
+ let backgroundColor = LX.getThemeColor( "global-selected" );
6572
+
6573
+ if( progress.low != undefined && progress.value < progress.low )
6574
+ {
6575
+ backgroundColor = LX.getThemeColor( "global-color-error" );
6576
+ }
6577
+ else if( progress.high != undefined && progress.value < progress.high )
6578
+ {
6579
+ backgroundColor = LX.getThemeColor( "global-color-warning" );
6580
+ }
6581
+
6582
+ progress.style.background = `color-mix(in srgb, ${backgroundColor} 20%, transparent)`;
6583
+ };
6305
6584
 
6306
6585
  container.appendChild( progress );
6307
6586
  element.appendChild( container );
@@ -6367,6 +6646,8 @@ class Panel {
6367
6646
  }
6368
6647
  }
6369
6648
 
6649
+ _updateColor();
6650
+
6370
6651
  return widget;
6371
6652
  }
6372
6653
 
@@ -6376,6 +6657,7 @@ class Panel {
6376
6657
  * @param {Function} callback Callback function on change
6377
6658
  * @param {*} options:
6378
6659
  * local: Ask for local file
6660
+ * disabled: Make the widget disabled [false]
6379
6661
  * read: Return the file itself (False) or the contents (True)
6380
6662
  * type: type to read as [text (Default), buffer, bin, url]
6381
6663
  */
@@ -6396,8 +6678,10 @@ class Panel {
6396
6678
 
6397
6679
  // Create hidden input
6398
6680
  let input = document.createElement( 'input' );
6681
+ input.className = "lexfileinput";
6399
6682
  input.style.width = "calc( 100% - " + LX.DEFAULT_NAME_WIDTH + " - 10%)";
6400
6683
  input.type = 'file';
6684
+ input.disabled = options.disabled ?? false;
6401
6685
 
6402
6686
  if( options.placeholder )
6403
6687
  {
@@ -7215,8 +7499,8 @@ class ContextMenu {
7215
7499
 
7216
7500
  this.root = document.createElement('div');
7217
7501
  this.root.className = "lexcontextmenubox";
7218
- this.root.style.left = (event.x - 48) + "px";
7219
- this.root.style.top = (event.y - 8) + "px";
7502
+ this.root.style.left = (event.x - 48 + document.scrollingElement.scrollLeft) + "px";
7503
+ this.root.style.top = (event.y - 8 + document.scrollingElement.scrollTop) + "px";
7220
7504
 
7221
7505
  this.root.addEventListener("mouseleave", function() {
7222
7506
  this.remove();
@@ -7505,7 +7789,7 @@ class Curve {
7505
7789
  element.style.minWidth = "50px";
7506
7790
  element.style.minHeight = "20px";
7507
7791
 
7508
- element.bgcolor = options.bgColor || LX.getThemeColor( "global-dark-background" );
7792
+ element.bgcolor = options.bgColor || LX.getThemeColor( "global-intense-background" );
7509
7793
  element.pointscolor = options.pointsColor || LX.getThemeColor( "global-selected-light" );
7510
7794
  element.linecolor = options.lineColor || "#555";
7511
7795
  element.value = value || [];
@@ -7520,6 +7804,12 @@ class Curve {
7520
7804
  element.smooth = (options.smooth && typeof( options.smooth ) == 'number' ? options.smooth : 0.3) || false;
7521
7805
  element.move_out = options.moveOutAction ?? LX.CURVE_MOVEOUT_DELETE;
7522
7806
 
7807
+ LX.addSignal( "@on_new_color_scheme", (el, value) => {
7808
+ element.bgcolor = options.bgColor || LX.getThemeColor( "global-intense-background" );
7809
+ element.pointscolor = options.pointsColor || LX.getThemeColor( "global-selected-light" );
7810
+ this.redraw();
7811
+ } );
7812
+
7523
7813
  this.element = element;
7524
7814
 
7525
7815
  let canvas = document.createElement( "canvas" );
@@ -7823,39 +8113,368 @@ class Curve {
7823
8113
 
7824
8114
  LX.Curve = Curve;
7825
8115
 
7826
- class AssetViewEvent {
7827
-
7828
- static NONE = 0;
7829
- static ASSET_SELECTED = 1;
7830
- static ASSET_DELETED = 2;
7831
- static ASSET_RENAMED = 3;
7832
- static ASSET_CLONED = 4;
7833
- static ASSET_DBLCLICKED = 5;
7834
- static ENTER_FOLDER = 6;
7835
- static ASSET_CHECKED = 7;
8116
+ /**
8117
+ * @class Dial
8118
+ */
7836
8119
 
7837
- constructor( type, item, value ) {
7838
- this.type = type || TreeEvent.NONE;
7839
- this.item = item;
7840
- this.value = value;
7841
- this.multiple = false; // Multiple selection
7842
- }
8120
+ class Dial {
7843
8121
 
7844
- string() {
7845
- switch(this.type) {
7846
- case AssetViewEvent.NONE: return "assetview_event_none";
7847
- case AssetViewEvent.ASSET_SELECTED: return "assetview_event_selected";
7848
- case AssetViewEvent.ASSET_DELETED: return "assetview_event_deleted";
7849
- case AssetViewEvent.ASSET_RENAMED: return "assetview_event_renamed";
7850
- case AssetViewEvent.ASSET_CLONED: return "assetview_event_cloned";
7851
- case AssetViewEvent.ASSET_DBLCLICKED: return "assetview_event_dblclicked";
7852
- case AssetViewEvent.ENTER_FOLDER: return "assetview_event_enter_folder";
7853
- case AssetViewEvent.ASSET_CHECKED: return "assetview_event_checked";
7854
- }
7855
- }
7856
- };
8122
+ constructor( panel, value, options = {} ) {
7857
8123
 
7858
- LX.AssetViewEvent = AssetViewEvent;
8124
+ let element = document.createElement( "div" );
8125
+ element.className = "dial " + ( options.className ? options.className : "" );
8126
+ element.style.width = element.style.height = options.size || "100%";
8127
+ element.style.minWidth = element.style.minHeight = "50px";
8128
+
8129
+ element.bgcolor = options.bgColor || LX.getThemeColor( "global-dark-background" );
8130
+ element.pointscolor = options.pointsColor || LX.getThemeColor( "global-selected-light" );
8131
+ element.linecolor = options.lineColor || "#555";
8132
+ element.value = value || [];
8133
+ element.xrange = options.xrange || [ 0, 1 ]; // min, max
8134
+ element.yrange = options.yrange || [ 0, 1 ]; // min, max
8135
+ element.defaulty = options.defaulty != null ? options.defaulty : 0.0;
8136
+ element.no_overlap = options.noOverlap || false;
8137
+ element.show_samples = options.showSamples || 0;
8138
+ element.allow_add_values = options.allowAddValues ?? true;
8139
+ element.draggable_x = options.draggableX ?? true;
8140
+ element.draggable_y = options.draggableY ?? true;
8141
+ element.smooth = (options.smooth && typeof( options.smooth ) == 'number' ? options.smooth : 0.3) || false;
8142
+ element.move_out = options.moveOutAction ?? LX.CURVE_MOVEOUT_DELETE;
8143
+
8144
+ this.element = element;
8145
+
8146
+ let canvas = document.createElement( "canvas" );
8147
+ canvas.width = canvas.height = options.size || 200;
8148
+ element.appendChild( canvas );
8149
+ this.canvas = canvas;
8150
+
8151
+ element.addEventListener( "mousedown", onmousedown );
8152
+
8153
+ element.getValueAt = function( x ) {
8154
+
8155
+ if( x < element.xrange[ 0 ] || x > element.xrange[ 1 ] )
8156
+ {
8157
+ return element.defaulty;
8158
+ }
8159
+
8160
+ var last = [ element.xrange[ 0 ], element.defaulty ];
8161
+ var f = 0;
8162
+ for( var i = 0; i < element.value.length; i += 1 )
8163
+ {
8164
+ var v = element.value[ i ];
8165
+ if( x == v[ 0 ] ) return v[ 1 ];
8166
+ if( x < v[ 0 ] )
8167
+ {
8168
+ f = ( x - last[ 0 ] ) / (v[ 0 ] - last[ 0 ]);
8169
+ return last[ 1 ] * ( 1 - f ) + v[ 1 ] * f;
8170
+ }
8171
+
8172
+ last = v;
8173
+ }
8174
+
8175
+ v = [ element.xrange[ 1 ], element.defaulty ];
8176
+ f = (x - last[ 0 ]) / (v[ 0 ] - last[ 0 ]);
8177
+ return last[ 1 ] * ( 1 - f ) + v[ 1 ] * f;
8178
+ }
8179
+
8180
+ element.resample = function( samples ) {
8181
+
8182
+ var r = [];
8183
+ var dx = (element.xrange[1] - element.xrange[ 0 ]) / samples;
8184
+ for(var i = element.xrange[0]; i <= element.xrange[1]; i += dx)
8185
+ {
8186
+ r.push( element.getValueAt(i) );
8187
+ }
8188
+ return r;
8189
+ }
8190
+
8191
+ element.addValue = function(v) {
8192
+
8193
+ for(var i = 0; i < element.value; i++) {
8194
+ var value = element.value[i];
8195
+ if(value[0] < v[0]) continue;
8196
+ element.value.splice(i,0,v);
8197
+ redraw();
8198
+ return;
8199
+ }
8200
+
8201
+ element.value.push(v);
8202
+ redraw();
8203
+ }
8204
+
8205
+ //value to canvas
8206
+ function convert(v, r) {
8207
+
8208
+ Math.pow(v[0],2)
8209
+ return [ canvas.width * ( v[0] - element.xrange[0])/ (element.xrange[1]),
8210
+ canvas.height * (v[1] - element.yrange[0])/ (element.yrange[1])];
8211
+ }
8212
+
8213
+ //canvas to value
8214
+ function unconvert(v) {
8215
+ return [(v[0] * element.xrange[1] / canvas.width + element.xrange[0]),
8216
+ (v[1] * element.yrange[1] / canvas.height + element.yrange[0])];
8217
+ }
8218
+
8219
+ var selected = -1;
8220
+
8221
+ element.redraw = function( o = {} ) {
8222
+
8223
+ if( o.value ) element.value = o.value;
8224
+ if( o.xrange ) element.xrange = o.xrange;
8225
+ if( o.yrange ) element.yrange = o.yrange;
8226
+ if( o.smooth ) element.smooth = o.smooth;
8227
+ var rect = canvas.parentElement.getBoundingClientRect();
8228
+ if( canvas.parentElement.parentElement ) rect = canvas.parentElement.parentElement.getBoundingClientRect();
8229
+ if( rect && canvas.width != rect.width && rect.width && rect.width < 1000 )
8230
+ {
8231
+ canvas.width = rect.width;
8232
+ }
8233
+
8234
+ var ctx = canvas.getContext( "2d" );
8235
+ ctx.setTransform( 1, 0, 0, 1, 0, 0 );
8236
+ ctx.translate( 0, canvas.height );
8237
+ ctx.scale( 1, -1 );
8238
+
8239
+ ctx.fillStyle = element.bgcolor;
8240
+ ctx.fillRect(0,0,canvas.width,canvas.height);
8241
+
8242
+ ctx.strokeStyle = element.linecolor;
8243
+ ctx.beginPath();
8244
+
8245
+ //draw line
8246
+ var pos = convert([ element.xrange[ 0 ],element.defaulty ]);
8247
+ ctx.moveTo( pos[ 0 ], pos[ 1 ] );
8248
+ let values = [pos[ 0 ], pos[ 1 ]];
8249
+
8250
+ for(var i in element.value) {
8251
+ var value = element.value[i];
8252
+ pos = convert(value);
8253
+ values.push(pos[ 0 ]);
8254
+ values.push(pos[ 1 ]);
8255
+
8256
+ }
8257
+
8258
+ pos = convert([ element.xrange[ 1 ], element.defaulty ]);
8259
+ values.push(pos[ 0 ]);
8260
+ values.push(pos[ 1 ]);
8261
+
8262
+ // Draw points
8263
+ const center = [0,0];
8264
+ pos = convert(center)
8265
+ ctx.fillStyle = "gray";
8266
+ ctx.beginPath();
8267
+ ctx.arc( pos[ 0 ], pos[ 1 ], 3, 0, Math.PI * 2);
8268
+ ctx.fill();
8269
+
8270
+ for( var i = 0; i < element.value.length; i += 1 ) {
8271
+ var value = element.value[ i ];
8272
+ pos = convert( value );
8273
+ if( selected == i )
8274
+ ctx.fillStyle = "white";
8275
+ else
8276
+ ctx.fillStyle = element.pointscolor;
8277
+ ctx.beginPath();
8278
+ ctx.arc( pos[ 0 ], pos[ 1 ], selected == i ? 4 : 3, 0, Math.PI * 2);
8279
+ ctx.fill();
8280
+ }
8281
+
8282
+ if(element.show_samples) {
8283
+ var samples = element.resample(element.show_samples);
8284
+ ctx.fillStyle = "#888";
8285
+ for(var i = 0; i < samples.length; i += 1)
8286
+ {
8287
+ var value = [ i * ((element.xrange[ 1 ] - element.xrange[ 0 ]) / element.show_samples) + element.xrange[ 0 ], samples[ i ] ];
8288
+ pos = convert(value);
8289
+ ctx.beginPath();
8290
+ ctx.arc( pos[ 0 ], pos[ 1 ], 2, 0, Math.PI * 2);
8291
+ ctx.fill();
8292
+ }
8293
+ }
8294
+ }
8295
+
8296
+ var last_mouse = [ 0, 0 ];
8297
+
8298
+ function onmousedown( e ) {
8299
+ document.addEventListener( "mousemove", onmousemove );
8300
+ document.addEventListener( "mouseup", onmouseup );
8301
+
8302
+ var rect = canvas.getBoundingClientRect();
8303
+ var mousex = e.clientX - rect.left;
8304
+ var mousey = e.clientY - rect.top;
8305
+
8306
+ selected = computeSelected( mousex, canvas.height - mousey );
8307
+
8308
+ if( e.button == LX.MOUSE_LEFT_CLICK && selected == -1 && element.allow_add_values ) {
8309
+ var v = unconvert([ mousex, canvas.height - mousey ]);
8310
+ element.value.push( v );
8311
+ sortValues();
8312
+ selected = element.value.indexOf( v );
8313
+ }
8314
+
8315
+ last_mouse = [ mousex, mousey ];
8316
+ element.redraw();
8317
+ e.preventDefault();
8318
+ e.stopPropagation();
8319
+ }
8320
+
8321
+ function onmousemove( e ) {
8322
+
8323
+ var rect = canvas.getBoundingClientRect();
8324
+ var mousex = e.clientX - rect.left;
8325
+ var mousey = e.clientY - rect.top;
8326
+
8327
+ if( mousex < 0 ) mousex = 0;
8328
+ else if( mousex > canvas.width ) mousex = canvas.width;
8329
+ if( mousey < 0 ) mousey = 0;
8330
+ else if( mousey > canvas.height ) mousey = canvas.height;
8331
+
8332
+ // Dragging to remove
8333
+ const currentMouseDiff = [ e.clientX - rect.left, e.clientY - rect.top ];
8334
+ if( selected != -1 && distance( currentMouseDiff, [ mousex, mousey ] ) > canvas.height * 0.5 )
8335
+ {
8336
+ if( element.move_out == LX.CURVE_MOVEOUT_DELETE)
8337
+ {
8338
+ element.value.splice( selected, 1 );
8339
+ }
8340
+ else
8341
+ {
8342
+ const d = [ currentMouseDiff[ 0 ] - mousex, currentMouseDiff[ 1 ] - mousey ];
8343
+ let value = element.value[ selected ];
8344
+ value[ 0 ] = ( d[ 0 ] == 0.0 ) ? value[ 0 ] : ( d[ 0 ] < 0.0 ? element.xrange[ 0 ] : element.xrange[ 1 ] );
8345
+ value[ 1 ] = ( d[ 1 ] == 0.0 ) ? value[ 1 ] : ( d[ 1 ] < 0.0 ? element.yrange[ 1 ] : element.yrange[ 0 ] );
8346
+ }
8347
+
8348
+ onmouseup( e );
8349
+ return;
8350
+ }
8351
+
8352
+ var dx = element.draggable_x ? last_mouse[ 0 ] - mousex : 0;
8353
+ var dy = element.draggable_y ? last_mouse[ 1 ] - mousey : 0;
8354
+ var delta = unconvert([ -dx, dy ]);
8355
+
8356
+ if( selected != -1 ) {
8357
+ var minx = element.xrange[ 0 ];
8358
+ var maxx = element.xrange[ 1 ];
8359
+
8360
+ if( element.no_overlap )
8361
+ {
8362
+ if( selected > 0) minx = element.value[ selected - 1 ][ 0 ];
8363
+ if( selected < ( element.value.length - 1 ) ) maxx = element.value[ selected + 1 ][ 0 ];
8364
+ }
8365
+
8366
+ var v = element.value[selected];
8367
+ v[ 0 ] += delta[ 0 ];
8368
+ v[ 1 ] += delta[ 1 ];
8369
+ if(v[ 0 ] < minx) v[ 0 ] = minx;
8370
+ else if(v[ 0 ] > maxx) v[ 0 ] = maxx;
8371
+ if(v[ 1 ] < element.yrange[ 0 ]) v[ 1 ] = element.yrange[ 0 ];
8372
+ else if(v[ 1 ] > element.yrange[ 1 ]) v[ 1 ] = element.yrange[ 1 ];
8373
+ }
8374
+
8375
+ sortValues();
8376
+ element.redraw();
8377
+ last_mouse[ 0 ] = mousex;
8378
+ last_mouse[ 1 ] = mousey;
8379
+ onchange( e );
8380
+
8381
+ e.preventDefault();
8382
+ e.stopPropagation();
8383
+ }
8384
+
8385
+ function onmouseup( e ) {
8386
+ selected = -1;
8387
+ element.redraw();
8388
+ document.removeEventListener("mousemove", onmousemove);
8389
+ document.removeEventListener("mouseup", onmouseup);
8390
+ onchange(e);
8391
+ e.preventDefault();
8392
+ e.stopPropagation();
8393
+ }
8394
+
8395
+ function onchange( e ) {
8396
+ if( options.callback )
8397
+ options.callback.call( element, element.value, e );
8398
+ }
8399
+
8400
+ function distance(a,b) { return Math.sqrt( Math.pow(b[0]-a[0],2) + Math.pow(b[1]-a[1],2) ); };
8401
+
8402
+ function computeSelected( x, y ) {
8403
+
8404
+ var minDistance = 100000;
8405
+ var maxDistance = 8; //pixels
8406
+ var selected = -1;
8407
+ for( var i = 0; i < element.value.length; i++ )
8408
+ {
8409
+ var value = element.value[ i ];
8410
+ var pos = convert( value );
8411
+ var dist = distance( [ x,y ], pos );
8412
+ if( dist < minDistance && dist < maxDistance )
8413
+ {
8414
+ minDistance = dist;
8415
+ selected = i;
8416
+ }
8417
+ }
8418
+ return selected;
8419
+ }
8420
+
8421
+ function sortValues() {
8422
+ var v = null;
8423
+ if( selected != -1 )
8424
+ {
8425
+ v = element.value[ selected ];
8426
+ }
8427
+ element.value.sort(function( a,b ) { return a[ 0 ] - b[ 0 ]; });
8428
+ if( v )
8429
+ {
8430
+ selected = element.value.indexOf( v );
8431
+ }
8432
+ }
8433
+
8434
+ element.redraw();
8435
+ return this;
8436
+ }
8437
+
8438
+ redraw( options = {} ) {
8439
+ this.element.redraw( options );
8440
+ }
8441
+ }
8442
+
8443
+ LX.Dial = Dial;
8444
+
8445
+ class AssetViewEvent {
8446
+
8447
+ static NONE = 0;
8448
+ static ASSET_SELECTED = 1;
8449
+ static ASSET_DELETED = 2;
8450
+ static ASSET_RENAMED = 3;
8451
+ static ASSET_CLONED = 4;
8452
+ static ASSET_DBLCLICKED = 5;
8453
+ static ENTER_FOLDER = 6;
8454
+ static ASSET_CHECKED = 7;
8455
+
8456
+ constructor( type, item, value ) {
8457
+ this.type = type || TreeEvent.NONE;
8458
+ this.item = item;
8459
+ this.value = value;
8460
+ this.multiple = false; // Multiple selection
8461
+ }
8462
+
8463
+ string() {
8464
+ switch(this.type) {
8465
+ case AssetViewEvent.NONE: return "assetview_event_none";
8466
+ case AssetViewEvent.ASSET_SELECTED: return "assetview_event_selected";
8467
+ case AssetViewEvent.ASSET_DELETED: return "assetview_event_deleted";
8468
+ case AssetViewEvent.ASSET_RENAMED: return "assetview_event_renamed";
8469
+ case AssetViewEvent.ASSET_CLONED: return "assetview_event_cloned";
8470
+ case AssetViewEvent.ASSET_DBLCLICKED: return "assetview_event_dblclicked";
8471
+ case AssetViewEvent.ENTER_FOLDER: return "assetview_event_enter_folder";
8472
+ case AssetViewEvent.ASSET_CHECKED: return "assetview_event_checked";
8473
+ }
8474
+ }
8475
+ };
8476
+
8477
+ LX.AssetViewEvent = AssetViewEvent;
7859
8478
 
7860
8479
  /**
7861
8480
  * @class AssetView
@@ -7898,6 +8517,7 @@ class AssetView {
7898
8517
  this.skipPreview = options.skipPreview ?? false;
7899
8518
  this.useNativeTitle = options.useNativeTitle ?? false;
7900
8519
  this.onlyFolders = options.onlyFolders ?? true;
8520
+ this.allowMultipleSelection = options.allowMultipleSelection ?? false;
7901
8521
  this.previewActions = options.previewActions ?? [];
7902
8522
  this.contextMenu = options.contextMenu ?? [];
7903
8523
  this.onRefreshContent = options.onRefreshContent;
@@ -8296,15 +8916,13 @@ class AssetView {
8296
8916
  itemEl.title = type + ": " + item.id;
8297
8917
  }
8298
8918
 
8299
- if( item.selected != undefined )
8919
+ if( that.allowMultipleSelection )
8300
8920
  {
8301
- let span = document.createElement('span');
8302
- span.className = "lexcheckbox";
8303
- let checkbox_input = document.createElement('input');
8304
- checkbox_input.type = "checkbox";
8305
- checkbox_input.className = "checkbox";
8306
- checkbox_input.checked = item.selected;
8307
- checkbox_input.addEventListener('change', ( e, v ) => {
8921
+ let checkbox = document.createElement( 'input' );
8922
+ checkbox.type = "checkbox";
8923
+ checkbox.className = "lexcheckbox";
8924
+ checkbox.checked = item.selected;
8925
+ checkbox.addEventListener('change', ( e, v ) => {
8308
8926
  item.selected = !item.selected;
8309
8927
  if( that.onevent )
8310
8928
  {
@@ -8314,10 +8932,9 @@ class AssetView {
8314
8932
  }
8315
8933
  e.stopPropagation();
8316
8934
  e.stopImmediatePropagation();
8317
- })
8318
- span.appendChild(checkbox_input);
8319
- itemEl.appendChild(span);
8935
+ });
8320
8936
 
8937
+ itemEl.appendChild( checkbox );
8321
8938
  }
8322
8939
 
8323
8940
  let title = document.createElement('span');
@@ -8383,6 +9000,7 @@ class AssetView {
8383
9000
  }
8384
9001
 
8385
9002
  this.classList.add('selected');
9003
+ that.selectedItem = item;
8386
9004
 
8387
9005
  if( !that.skipPreview )
8388
9006
  {