lexgui 0.1.46 → 0.2.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/codeeditor.js +12 -10
- package/build/lexgui.css +345 -119
- package/build/lexgui.js +8313 -7874
- package/build/lexgui.min.css +1 -0
- package/build/lexgui.min.js +1 -0
- package/build/lexgui.module.js +624 -204
- package/build/lexgui.module.min.js +1 -0
- package/changelog.md +24 -2
- package/demo.js +89 -873
- package/package.json +1 -1
package/build/lexgui.module.js
CHANGED
|
@@ -8,10 +8,11 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
var LX = {
|
|
11
|
-
version: "0.
|
|
11
|
+
version: "0.2.0",
|
|
12
12
|
ready: false,
|
|
13
13
|
components: [], // specific pre-build components
|
|
14
|
-
signals: {} // events and triggers
|
|
14
|
+
signals: {}, // events and triggers
|
|
15
|
+
extraCommandbarEntries: [] // user specific entries for command bar
|
|
15
16
|
};
|
|
16
17
|
|
|
17
18
|
LX.MOUSE_LEFT_CLICK = 0;
|
|
@@ -161,12 +162,13 @@ function getThemeColor( colorName )
|
|
|
161
162
|
{
|
|
162
163
|
const r = getComputedStyle( document.querySelector( ':root' ) );
|
|
163
164
|
const value = r.getPropertyValue( '--' + colorName );
|
|
165
|
+
const theme = document.documentElement.getAttribute( "data-theme" );
|
|
164
166
|
|
|
165
|
-
if( value.includes( "light-dark" )
|
|
167
|
+
if( value.includes( "light-dark" ) )
|
|
166
168
|
{
|
|
167
169
|
const currentScheme = r.getPropertyValue( "color-scheme" );
|
|
168
170
|
|
|
169
|
-
if(
|
|
171
|
+
if( currentScheme == "light" )
|
|
170
172
|
{
|
|
171
173
|
return value.substring( value.indexOf( '(' ) + 1, value.indexOf( ',' ) ).replace( /\s/g, '' );
|
|
172
174
|
}
|
|
@@ -404,6 +406,9 @@ LX.makeDraggable = makeDraggable;
|
|
|
404
406
|
* language (String):
|
|
405
407
|
* windowMode (Boolean):
|
|
406
408
|
* lineNumbers (Boolean):
|
|
409
|
+
* firstLine (Number): TODO
|
|
410
|
+
* linesAdded (Array):
|
|
411
|
+
* linesRemoved (Array):
|
|
407
412
|
* tabName (String):
|
|
408
413
|
*/
|
|
409
414
|
function makeCodeSnippet( code, size, options = { } )
|
|
@@ -416,16 +421,15 @@ function makeCodeSnippet( code, size, options = { } )
|
|
|
416
421
|
|
|
417
422
|
const snippet = document.createElement( "div" );
|
|
418
423
|
snippet.className = "lexcodesnippet";
|
|
419
|
-
snippet.style.width = size[ 0 ];
|
|
420
|
-
snippet.style.height = size[ 1 ];
|
|
424
|
+
snippet.style.width = size ? size[ 0 ] : "auto";
|
|
425
|
+
snippet.style.height = size ? size[ 1 ] : "auto";
|
|
421
426
|
const area = new Area( { noAppend: true } );
|
|
422
427
|
let editor = new LX.CodeEditor( area, {
|
|
423
428
|
skipInfo: true,
|
|
424
429
|
disableEdition: true,
|
|
425
430
|
allowAddScripts: false,
|
|
426
431
|
name: options.tabName,
|
|
427
|
-
// showTab: options.showTab ?? true
|
|
428
|
-
// lineNumbers: options.lineNumbers ?? true
|
|
432
|
+
// showTab: options.showTab ?? true
|
|
429
433
|
} );
|
|
430
434
|
editor.setText( code, options.language ?? "Plain Text" );
|
|
431
435
|
|
|
@@ -484,12 +488,30 @@ function makeCodeSnippet( code, size, options = { } )
|
|
|
484
488
|
tabs.prepend( windowActionButtons );
|
|
485
489
|
}
|
|
486
490
|
|
|
491
|
+
if( !( options.lineNumbers ?? true ) )
|
|
492
|
+
{
|
|
493
|
+
editor.root.classList.add( "no-gutter" );
|
|
494
|
+
}
|
|
495
|
+
|
|
487
496
|
snippet.appendChild( area.root );
|
|
488
497
|
return snippet;
|
|
489
498
|
}
|
|
490
499
|
|
|
491
500
|
LX.makeCodeSnippet = makeCodeSnippet;
|
|
492
501
|
|
|
502
|
+
/**
|
|
503
|
+
* @method registerCommandbarEntry
|
|
504
|
+
* @description Adds an extra command bar entry
|
|
505
|
+
* @param {String} name
|
|
506
|
+
* @param {Function} callback
|
|
507
|
+
*/
|
|
508
|
+
function registerCommandbarEntry( name, callback )
|
|
509
|
+
{
|
|
510
|
+
LX.extraCommandbarEntries.push( { name, callback } );
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
LX.registerCommandbarEntry = registerCommandbarEntry;
|
|
514
|
+
|
|
493
515
|
// Math classes
|
|
494
516
|
|
|
495
517
|
class vec2 {
|
|
@@ -518,24 +540,23 @@ class vec2 {
|
|
|
518
540
|
|
|
519
541
|
LX.vec2 = vec2;
|
|
520
542
|
|
|
521
|
-
function
|
|
543
|
+
function _createCommandbar( root )
|
|
522
544
|
{
|
|
523
|
-
let
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
root.appendChild( globalSearch );
|
|
545
|
+
let commandbar = document.createElement( "dialog" );
|
|
546
|
+
commandbar.className = "commandbar";
|
|
547
|
+
commandbar.tabIndex = -1;
|
|
548
|
+
root.appendChild( commandbar );
|
|
528
549
|
|
|
529
550
|
let allItems = [];
|
|
530
551
|
let hoverElId = null;
|
|
531
552
|
|
|
532
|
-
|
|
553
|
+
commandbar.addEventListener('keydown', function( e ) {
|
|
533
554
|
e.stopPropagation();
|
|
534
555
|
e.stopImmediatePropagation();
|
|
535
556
|
hoverElId = hoverElId ?? -1;
|
|
536
557
|
if( e.key == 'Escape' )
|
|
537
558
|
{
|
|
538
|
-
this.
|
|
559
|
+
this.close();
|
|
539
560
|
_resetBar( true );
|
|
540
561
|
}
|
|
541
562
|
else if( e.key == 'Enter' )
|
|
@@ -544,7 +565,7 @@ function create_global_searchbar( root )
|
|
|
544
565
|
if( el )
|
|
545
566
|
{
|
|
546
567
|
const isCheckbox = (el.item.type && el.item.type === 'checkbox');
|
|
547
|
-
this.
|
|
568
|
+
this.close();
|
|
548
569
|
if( isCheckbox )
|
|
549
570
|
{
|
|
550
571
|
el.item.checked = !el.item.checked;
|
|
@@ -559,7 +580,7 @@ function create_global_searchbar( root )
|
|
|
559
580
|
else if ( e.key == 'ArrowDown' && hoverElId < (allItems.length - 1) )
|
|
560
581
|
{
|
|
561
582
|
hoverElId++;
|
|
562
|
-
|
|
583
|
+
commandbar.querySelectorAll(".hovered").forEach(e => e.classList.remove('hovered'));
|
|
563
584
|
allItems[ hoverElId ].classList.add('hovered');
|
|
564
585
|
|
|
565
586
|
let dt = allItems[ hoverElId ].offsetHeight * (hoverElId + 1) - itemContainer.offsetHeight;
|
|
@@ -574,19 +595,19 @@ function create_global_searchbar( root )
|
|
|
574
595
|
} else if ( e.key == 'ArrowUp' && hoverElId > 0 )
|
|
575
596
|
{
|
|
576
597
|
hoverElId--;
|
|
577
|
-
|
|
598
|
+
commandbar.querySelectorAll(".hovered").forEach(e => e.classList.remove('hovered'));
|
|
578
599
|
allItems[ hoverElId ].classList.add('hovered');
|
|
579
600
|
}
|
|
580
601
|
});
|
|
581
602
|
|
|
582
|
-
|
|
603
|
+
commandbar.addEventListener('focusout', function( e ) {
|
|
583
604
|
if( e.relatedTarget == e.currentTarget )
|
|
584
605
|
{
|
|
585
606
|
return;
|
|
586
607
|
}
|
|
587
608
|
e.stopPropagation();
|
|
588
609
|
e.stopImmediatePropagation();
|
|
589
|
-
this.
|
|
610
|
+
this.close();
|
|
590
611
|
_resetBar( true );
|
|
591
612
|
});
|
|
592
613
|
|
|
@@ -595,9 +616,7 @@ function create_global_searchbar( root )
|
|
|
595
616
|
{
|
|
596
617
|
e.stopImmediatePropagation();
|
|
597
618
|
e.stopPropagation();
|
|
598
|
-
|
|
599
|
-
globalSearch.querySelector('input').focus();
|
|
600
|
-
_addElements( undefined );
|
|
619
|
+
LX.setCommandbarState( true );
|
|
601
620
|
}
|
|
602
621
|
else
|
|
603
622
|
{
|
|
@@ -675,22 +694,22 @@ function create_global_searchbar( root )
|
|
|
675
694
|
const isCheckbox = (i && i.type && i.type === 'checkbox');
|
|
676
695
|
if( isCheckbox )
|
|
677
696
|
{
|
|
678
|
-
searchItem.innerHTML = "<a class='fa fa-check'></a><span>" + p + t + "</span>"
|
|
697
|
+
searchItem.innerHTML = "<a class='fa fa-check'></a><span>" + ( p + t ) + "</span>"
|
|
679
698
|
}
|
|
680
699
|
else
|
|
681
700
|
{
|
|
682
|
-
searchItem.innerHTML = p + t;
|
|
701
|
+
searchItem.innerHTML = ( p + t );
|
|
683
702
|
}
|
|
684
703
|
searchItem.entry_name = t;
|
|
685
704
|
searchItem.callback = c;
|
|
686
705
|
searchItem.item = i;
|
|
687
706
|
searchItem.addEventListener('click', function(e) {
|
|
688
|
-
this.callback.call(window, this.entry_name);
|
|
689
|
-
|
|
707
|
+
this.callback.call( window, this.entry_name );
|
|
708
|
+
LX.setCommandbarState( false );
|
|
690
709
|
_resetBar( true );
|
|
691
710
|
});
|
|
692
711
|
searchItem.addEventListener('mouseenter', function(e) {
|
|
693
|
-
|
|
712
|
+
commandbar.querySelectorAll(".hovered").forEach(e => e.classList.remove('hovered'));
|
|
694
713
|
this.classList.add('hovered');
|
|
695
714
|
hoverElId = allItems.indexOf( this );
|
|
696
715
|
});
|
|
@@ -724,7 +743,7 @@ function create_global_searchbar( root )
|
|
|
724
743
|
_propagateAdd( c, filter, path );
|
|
725
744
|
};
|
|
726
745
|
|
|
727
|
-
|
|
746
|
+
commandbar._addElements = filter => {
|
|
728
747
|
|
|
729
748
|
_resetBar();
|
|
730
749
|
|
|
@@ -736,6 +755,16 @@ function create_global_searchbar( root )
|
|
|
736
755
|
}
|
|
737
756
|
}
|
|
738
757
|
|
|
758
|
+
for( let entry of LX.extraCommandbarEntries )
|
|
759
|
+
{
|
|
760
|
+
const name = entry.name;
|
|
761
|
+
if( !name.toLowerCase().includes( filter ) )
|
|
762
|
+
{
|
|
763
|
+
continue;
|
|
764
|
+
}
|
|
765
|
+
_addElement( name, entry.callback, "", {} );
|
|
766
|
+
}
|
|
767
|
+
|
|
739
768
|
if( LX.has('CodeEditor') )
|
|
740
769
|
{
|
|
741
770
|
const instances = LX.CodeEditor.getInstances();
|
|
@@ -753,7 +782,7 @@ function create_global_searchbar( root )
|
|
|
753
782
|
|
|
754
783
|
value += key + " <span class='lang-ext'>(" + languages[ l ].ext + ")</span>";
|
|
755
784
|
if( key.toLowerCase().includes( filter ) ) {
|
|
756
|
-
|
|
785
|
+
_addElement( value, () => {
|
|
757
786
|
for( let i of instances ) {
|
|
758
787
|
i._changeLanguage( l );
|
|
759
788
|
}
|
|
@@ -764,14 +793,14 @@ function create_global_searchbar( root )
|
|
|
764
793
|
}
|
|
765
794
|
|
|
766
795
|
input.addEventListener('input', function(e) {
|
|
767
|
-
_addElements( this.value.toLowerCase() );
|
|
796
|
+
commandbar._addElements( this.value.toLowerCase() );
|
|
768
797
|
});
|
|
769
798
|
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
799
|
+
commandbar.appendChild( header );
|
|
800
|
+
commandbar.appendChild( tabArea.root );
|
|
801
|
+
commandbar.appendChild( itemContainer );
|
|
773
802
|
|
|
774
|
-
return
|
|
803
|
+
return commandbar;
|
|
775
804
|
}
|
|
776
805
|
|
|
777
806
|
/**
|
|
@@ -781,6 +810,7 @@ function create_global_searchbar( root )
|
|
|
781
810
|
* id: Id of the main area
|
|
782
811
|
* skipRoot: Skip adding LX root container
|
|
783
812
|
* skipDefaultArea: Skip creation of main area
|
|
813
|
+
* strictViewport: Use only window area
|
|
784
814
|
*/
|
|
785
815
|
|
|
786
816
|
function init( options = { } )
|
|
@@ -803,16 +833,17 @@ function init( options = { } )
|
|
|
803
833
|
this.root = root;
|
|
804
834
|
this.container = document.body;
|
|
805
835
|
|
|
806
|
-
// this.modal.toggleAttribute( 'hidden', true );
|
|
807
|
-
// this.modal.toggle = function( force ) { this.toggleAttribute( 'hidden', force ); };
|
|
808
|
-
|
|
809
836
|
this.modal.classList.add( 'hiddenOpacity' );
|
|
810
837
|
this.modal.toggle = function( force ) { this.classList.toggle( 'hiddenOpacity', force ); };
|
|
811
838
|
|
|
812
839
|
if( options.container )
|
|
840
|
+
{
|
|
813
841
|
this.container = document.getElementById( options.container );
|
|
842
|
+
}
|
|
814
843
|
|
|
815
|
-
|
|
844
|
+
document.documentElement.setAttribute( "data-strictVP", ( options.strictViewport ?? true ) ? "true" : "false" );
|
|
845
|
+
|
|
846
|
+
this.commandbar = _createCommandbar( this.container );
|
|
816
847
|
|
|
817
848
|
this.container.appendChild( modal );
|
|
818
849
|
|
|
@@ -856,16 +887,48 @@ function init( options = { } )
|
|
|
856
887
|
this.main_area = new Area( { id: options.id ?? 'mainarea' } );
|
|
857
888
|
}
|
|
858
889
|
|
|
859
|
-
window.matchMedia( "(prefers-color-scheme:
|
|
860
|
-
|
|
861
|
-
LX.
|
|
862
|
-
|
|
890
|
+
if( ( options.autoTheme ?? true ) && window.matchMedia && window.matchMedia( "(prefers-color-scheme: light)" ).matches )
|
|
891
|
+
{
|
|
892
|
+
LX.setTheme( "light" );
|
|
893
|
+
|
|
894
|
+
window.matchMedia( "(prefers-color-scheme: dark)" ).addEventListener( "change", event => {
|
|
895
|
+
LX.setTheme( event.matches ? "dark" : "light" );
|
|
896
|
+
});
|
|
897
|
+
}
|
|
863
898
|
|
|
864
899
|
return this.main_area;
|
|
865
900
|
}
|
|
866
901
|
|
|
867
902
|
LX.init = init;
|
|
868
903
|
|
|
904
|
+
/**
|
|
905
|
+
* @method setCommandbarState
|
|
906
|
+
* @param {Boolean} value
|
|
907
|
+
* @param {Boolean} resetEntries
|
|
908
|
+
*/
|
|
909
|
+
|
|
910
|
+
function setCommandbarState( value, resetEntries = true )
|
|
911
|
+
{
|
|
912
|
+
const cb = this.commandbar;
|
|
913
|
+
|
|
914
|
+
if( value )
|
|
915
|
+
{
|
|
916
|
+
cb.show();
|
|
917
|
+
cb.querySelector('input').focus();
|
|
918
|
+
|
|
919
|
+
if( resetEntries )
|
|
920
|
+
{
|
|
921
|
+
cb._addElements( undefined );
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
else
|
|
925
|
+
{
|
|
926
|
+
cb.close();
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
LX.setCommandbarState = setCommandbarState;
|
|
931
|
+
|
|
869
932
|
/**
|
|
870
933
|
* @method message
|
|
871
934
|
* @param {String} text
|
|
@@ -898,9 +961,9 @@ LX.message = message;
|
|
|
898
961
|
* @param {String} title (Optional)
|
|
899
962
|
* @param {*} options
|
|
900
963
|
* id: Id of the message dialog
|
|
901
|
-
*
|
|
902
|
-
* position
|
|
903
|
-
* size
|
|
964
|
+
* timeout (Number): Delay time before it closes automatically (ms). Default: [3000]
|
|
965
|
+
* position (Array): [x,y] Dialog position in screen. Default: [screen centered]
|
|
966
|
+
* size (Array): [width, height]
|
|
904
967
|
*/
|
|
905
968
|
|
|
906
969
|
function popup( text, title, options = {} )
|
|
@@ -910,7 +973,7 @@ function popup( text, title, options = {} )
|
|
|
910
973
|
throw("No message to show");
|
|
911
974
|
}
|
|
912
975
|
|
|
913
|
-
options.size = options.size ?? [ "
|
|
976
|
+
options.size = options.size ?? [ "max-content", "auto" ];
|
|
914
977
|
options.class = "lexpopup";
|
|
915
978
|
|
|
916
979
|
const time = options.timeout || 3000;
|
|
@@ -918,13 +981,9 @@ function popup( text, title, options = {} )
|
|
|
918
981
|
p.addTextArea( null, text, null, { disabled: true, fitHeight: true } );
|
|
919
982
|
}, options );
|
|
920
983
|
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
dialog.root.classList.add( 'fadeout' );
|
|
925
|
-
}, time - 1000 );
|
|
926
|
-
|
|
927
|
-
setTimeout( dialog.close, time );
|
|
984
|
+
setTimeout( () => {
|
|
985
|
+
dialog.close();
|
|
986
|
+
}, Math.max( time, 150 ) );
|
|
928
987
|
|
|
929
988
|
return dialog;
|
|
930
989
|
}
|
|
@@ -1009,6 +1068,25 @@ function badge( text, className, options = {} )
|
|
|
1009
1068
|
|
|
1010
1069
|
LX.badge = badge;
|
|
1011
1070
|
|
|
1071
|
+
/**
|
|
1072
|
+
* @method makeContainer
|
|
1073
|
+
* @param {Array} size
|
|
1074
|
+
* @param {String} className
|
|
1075
|
+
* @param {Object} overrideStyle
|
|
1076
|
+
*/
|
|
1077
|
+
|
|
1078
|
+
function makeContainer( size, className, overrideStyle = {} )
|
|
1079
|
+
{
|
|
1080
|
+
const container = document.createElement( "div" );
|
|
1081
|
+
container.className = "lexcontainer " + ( className ?? "" );
|
|
1082
|
+
container.style.width = size && size[ 0 ] ? size[ 0 ] : "100%";
|
|
1083
|
+
container.style.height = size && size[ 1 ] ? size[ 1 ] : "100%";
|
|
1084
|
+
Object.assign( container.style, overrideStyle );
|
|
1085
|
+
return container;
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
LX.makeContainer = makeContainer;
|
|
1089
|
+
|
|
1012
1090
|
/*
|
|
1013
1091
|
* Events and Signals
|
|
1014
1092
|
*/
|
|
@@ -1491,8 +1569,8 @@ class Area {
|
|
|
1491
1569
|
}
|
|
1492
1570
|
|
|
1493
1571
|
area1.root.style.width = "100%";
|
|
1494
|
-
area1.root.style.height = "calc( " + height1 + " - " + data + " )";
|
|
1495
|
-
area2.root.style.height = "calc( " + height2 + " - " + data + " )";
|
|
1572
|
+
area1.root.style.height = ( height1 == "auto" ? height1 : "calc( " + height1 + " - " + data + " )");
|
|
1573
|
+
area2.root.style.height = ( height2 == "auto" ? height2 : "calc( " + height2 + " - " + data + " )");
|
|
1496
1574
|
}
|
|
1497
1575
|
}
|
|
1498
1576
|
|
|
@@ -2092,7 +2170,7 @@ class Tabs {
|
|
|
2092
2170
|
|
|
2093
2171
|
area.root.classList.add( "lexareatabscontainer" );
|
|
2094
2172
|
|
|
2095
|
-
area.split({type: 'vertical', sizes: "auto", resize: false, top: 6});
|
|
2173
|
+
area.split({type: 'vertical', sizes: options.sizes ?? "auto", resize: false, top: 6});
|
|
2096
2174
|
area.sections[0].attach( container );
|
|
2097
2175
|
|
|
2098
2176
|
this.area = area.sections[1];
|
|
@@ -2958,6 +3036,7 @@ class Widget {
|
|
|
2958
3036
|
static FORM = 27;
|
|
2959
3037
|
static DIAL = 28;
|
|
2960
3038
|
static COUNTER = 29;
|
|
3039
|
+
static TABLE = 30;
|
|
2961
3040
|
|
|
2962
3041
|
static NO_CONTEXT_TYPES = [
|
|
2963
3042
|
Widget.BUTTON,
|
|
@@ -3048,6 +3127,7 @@ class Widget {
|
|
|
3048
3127
|
case Widget.FORM: return "Form";
|
|
3049
3128
|
case Widget.DIAL: return "Dial";
|
|
3050
3129
|
case Widget.COUNTER: return "Counter";
|
|
3130
|
+
case Widget.TABLE: return "Table";
|
|
3051
3131
|
case Widget.CUSTOM: return this.customName;
|
|
3052
3132
|
}
|
|
3053
3133
|
|
|
@@ -4070,8 +4150,8 @@ class Panel {
|
|
|
4070
4150
|
|
|
4071
4151
|
let searchIcon = document.createElement('a');
|
|
4072
4152
|
searchIcon.className = "fa-solid fa-magnifying-glass";
|
|
4073
|
-
element.appendChild(input);
|
|
4074
4153
|
element.appendChild(searchIcon);
|
|
4154
|
+
element.appendChild(input);
|
|
4075
4155
|
|
|
4076
4156
|
input.addEventListener("input", (e) => {
|
|
4077
4157
|
if(options.callback)
|
|
@@ -4123,26 +4203,28 @@ class Panel {
|
|
|
4123
4203
|
}
|
|
4124
4204
|
}
|
|
4125
4205
|
|
|
4126
|
-
|
|
4127
|
-
|
|
4206
|
+
_filterOptions( options, value ) {
|
|
4207
|
+
|
|
4208
|
+
// Push to right container
|
|
4128
4209
|
const emptyFilter = !value.length;
|
|
4129
4210
|
let filteredOptions = [];
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
|
|
4211
|
+
|
|
4212
|
+
// Add widgets
|
|
4213
|
+
for( let i = 0; i < options.length; i++ )
|
|
4214
|
+
{
|
|
4215
|
+
let o = options[ i ];
|
|
4216
|
+
if( !emptyFilter )
|
|
4134
4217
|
{
|
|
4135
|
-
let toCompare = (typeof o == 'string') ? o : o.value;
|
|
4136
|
-
;
|
|
4218
|
+
let toCompare = ( typeof o == 'string' ) ? o : o.value;
|
|
4137
4219
|
const filterWord = value.toLowerCase();
|
|
4138
4220
|
const name = toCompare.toLowerCase();
|
|
4139
|
-
if(!name.includes(filterWord)) continue;
|
|
4221
|
+
if( !name.includes( filterWord ) ) continue;
|
|
4140
4222
|
}
|
|
4141
|
-
|
|
4142
|
-
filteredOptions.push(o);
|
|
4223
|
+
|
|
4224
|
+
filteredOptions.push( o );
|
|
4143
4225
|
}
|
|
4144
4226
|
|
|
4145
|
-
this.refresh(filteredOptions);
|
|
4227
|
+
this.refresh( filteredOptions );
|
|
4146
4228
|
}
|
|
4147
4229
|
|
|
4148
4230
|
_trigger( event, callback ) {
|
|
@@ -4629,66 +4711,82 @@ class Panel {
|
|
|
4629
4711
|
* @param {Array} values Each of the {value, callback} items
|
|
4630
4712
|
* @param {*} options:
|
|
4631
4713
|
* float: Justify content (left, center, right) [center]
|
|
4714
|
+
* selected: Selected item by default by value
|
|
4632
4715
|
* noSelection: Buttons can be clicked, but they are not selectable
|
|
4633
4716
|
*/
|
|
4634
4717
|
|
|
4635
4718
|
addComboButtons( name, values, options = {} ) {
|
|
4636
4719
|
|
|
4637
|
-
let widget = this.create_widget(name, Widget.BUTTON, options);
|
|
4720
|
+
let widget = this.create_widget( name, Widget.BUTTON, options );
|
|
4638
4721
|
let element = widget.domEl;
|
|
4639
4722
|
|
|
4640
4723
|
let that = this;
|
|
4641
4724
|
let container = document.createElement('div');
|
|
4642
4725
|
container.className = "lexcombobuttons ";
|
|
4643
|
-
|
|
4726
|
+
|
|
4727
|
+
if( options.float )
|
|
4728
|
+
{
|
|
4729
|
+
container.className += options.float;
|
|
4730
|
+
}
|
|
4731
|
+
|
|
4644
4732
|
container.style.width = "calc( 100% - " + LX.DEFAULT_NAME_WIDTH + ")";
|
|
4645
4733
|
|
|
4646
|
-
let
|
|
4734
|
+
let buttonsBox = document.createElement('div');
|
|
4735
|
+
buttonsBox.className = "lexcombobuttonsbox ";
|
|
4736
|
+
|
|
4737
|
+
let shouldSelect = !( options.noSelection ?? false );
|
|
4738
|
+
|
|
4647
4739
|
for( let b of values )
|
|
4648
4740
|
{
|
|
4649
|
-
if( !b.value )
|
|
4741
|
+
if( !b.value )
|
|
4742
|
+
{
|
|
4743
|
+
throw( "Set 'value' for each button!" );
|
|
4744
|
+
}
|
|
4650
4745
|
|
|
4651
4746
|
let buttonEl = document.createElement('button');
|
|
4652
4747
|
buttonEl.className = "lexbutton combo";
|
|
4653
4748
|
buttonEl.title = b.icon ? b.value : "";
|
|
4654
|
-
|
|
4655
|
-
buttonEl.classList.add(options.buttonClass);
|
|
4749
|
+
buttonEl.id = b.id ?? "";
|
|
4656
4750
|
|
|
4657
|
-
if(options.
|
|
4658
|
-
|
|
4751
|
+
if( options.buttonClass )
|
|
4752
|
+
{
|
|
4753
|
+
buttonEl.classList.add( options.buttonClass );
|
|
4754
|
+
}
|
|
4659
4755
|
|
|
4660
|
-
if(b.
|
|
4661
|
-
|
|
4756
|
+
if( shouldSelect && options.selected == b.value )
|
|
4757
|
+
{
|
|
4758
|
+
buttonEl.classList.add("selected");
|
|
4759
|
+
}
|
|
4662
4760
|
|
|
4663
|
-
buttonEl.innerHTML = (b.icon ? "<a class='" + b.icon +"'></a>" : "") + "<span>" + (b.icon ? "" : b.value) + "</span>";
|
|
4761
|
+
buttonEl.innerHTML = ( b.icon ? "<a class='" + b.icon +"'></a>" : "" ) + "<span>" + ( b.icon ? "" : b.value ) + "</span>";
|
|
4664
4762
|
|
|
4665
|
-
if(options.disabled)
|
|
4666
|
-
|
|
4763
|
+
if( options.disabled )
|
|
4764
|
+
{
|
|
4765
|
+
buttonEl.setAttribute( "disabled", true );
|
|
4766
|
+
}
|
|
4667
4767
|
|
|
4668
|
-
buttonEl.addEventListener("click", function(e) {
|
|
4669
|
-
if(
|
|
4768
|
+
buttonEl.addEventListener("click", function( e ) {
|
|
4769
|
+
if( shouldSelect )
|
|
4770
|
+
{
|
|
4670
4771
|
container.querySelectorAll('button').forEach( s => s.classList.remove('selected'));
|
|
4671
4772
|
this.classList.add('selected');
|
|
4672
4773
|
}
|
|
4673
|
-
that._trigger( new IEvent(name, b.value, e), b.callback );
|
|
4674
|
-
});
|
|
4675
4774
|
|
|
4676
|
-
|
|
4775
|
+
that._trigger( new IEvent( name, b.value, e ), b.callback );
|
|
4776
|
+
});
|
|
4677
4777
|
|
|
4678
|
-
|
|
4679
|
-
if(widget.name === undefined) {
|
|
4680
|
-
buttonEl.className += " noname";
|
|
4681
|
-
buttonEl.style.width = "100%";
|
|
4682
|
-
}
|
|
4778
|
+
buttonsBox.appendChild( buttonEl );
|
|
4683
4779
|
}
|
|
4684
4780
|
|
|
4685
4781
|
// Remove branch padding and margins
|
|
4686
|
-
if(widget.name
|
|
4782
|
+
if( !widget.name)
|
|
4783
|
+
{
|
|
4687
4784
|
element.className += " noname";
|
|
4688
4785
|
container.style.width = "100%";
|
|
4689
4786
|
}
|
|
4690
4787
|
|
|
4691
|
-
|
|
4788
|
+
container.appendChild( buttonsBox );
|
|
4789
|
+
element.appendChild( container );
|
|
4692
4790
|
|
|
4693
4791
|
return widget;
|
|
4694
4792
|
}
|
|
@@ -4940,6 +5038,8 @@ class Panel {
|
|
|
4940
5038
|
* filter: Add a search bar to the widget [false]
|
|
4941
5039
|
* disabled: Make the widget disabled [false]
|
|
4942
5040
|
* skipReset: Don't add the reset value button when value changes
|
|
5041
|
+
* placeholder: Placeholder for the filter input
|
|
5042
|
+
* emptyMsg: Custom message to show when no filtered results
|
|
4943
5043
|
*/
|
|
4944
5044
|
|
|
4945
5045
|
addDropdown( name, values, value, callback, options = {} ) {
|
|
@@ -4985,17 +5085,74 @@ class Panel {
|
|
|
4985
5085
|
let buttonName = value;
|
|
4986
5086
|
buttonName += "<a class='fa-solid fa-angle-down' style='float:right; margin-right: 3px;'></a>";
|
|
4987
5087
|
|
|
4988
|
-
this.queue(container);
|
|
5088
|
+
this.queue( container );
|
|
5089
|
+
|
|
5090
|
+
const _placeOptions = ( parent ) => {
|
|
5091
|
+
|
|
5092
|
+
console.log("Replacing container");
|
|
5093
|
+
|
|
5094
|
+
const overflowContainer = parent.getParentArea();
|
|
5095
|
+
const rect = selectedOption.getBoundingClientRect();
|
|
5096
|
+
const nestedDialog = parent.parentElement.closest( "dialog" );
|
|
5097
|
+
|
|
5098
|
+
// Manage vertical aspect
|
|
5099
|
+
{
|
|
5100
|
+
const listHeight = parent.offsetHeight;
|
|
5101
|
+
let topPosition = rect.y;
|
|
5102
|
+
|
|
5103
|
+
let maxY = window.innerHeight;
|
|
4989
5104
|
|
|
4990
|
-
|
|
5105
|
+
if( overflowContainer )
|
|
5106
|
+
{
|
|
5107
|
+
const parentRect = overflowContainer.getBoundingClientRect();
|
|
5108
|
+
maxY = parentRect.y + parentRect.height;
|
|
5109
|
+
}
|
|
5110
|
+
|
|
5111
|
+
if( nestedDialog )
|
|
5112
|
+
{
|
|
5113
|
+
const rect = nestedDialog.getBoundingClientRect();
|
|
5114
|
+
topPosition -= rect.y;
|
|
5115
|
+
}
|
|
5116
|
+
|
|
5117
|
+
parent.style.top = ( topPosition + selectedOption.offsetHeight ) + 'px';
|
|
5118
|
+
|
|
5119
|
+
const showAbove = ( topPosition + listHeight ) > maxY;
|
|
5120
|
+
if( showAbove )
|
|
5121
|
+
{
|
|
5122
|
+
parent.style.top = ( topPosition - listHeight ) + 'px';
|
|
5123
|
+
parent.classList.add( "place-above" );
|
|
5124
|
+
}
|
|
5125
|
+
}
|
|
4991
5126
|
|
|
4992
|
-
|
|
4993
|
-
for( let i of values )
|
|
5127
|
+
// Manage horizontal aspect
|
|
4994
5128
|
{
|
|
4995
|
-
const
|
|
4996
|
-
|
|
5129
|
+
const listWidth = parent.offsetWidth;
|
|
5130
|
+
let leftPosition = rect.x;
|
|
5131
|
+
|
|
5132
|
+
parent.style.minWidth = ( rect.width ) + 'px';
|
|
5133
|
+
|
|
5134
|
+
if( nestedDialog )
|
|
5135
|
+
{
|
|
5136
|
+
const rect = nestedDialog.getBoundingClientRect();
|
|
5137
|
+
leftPosition -= rect.x;
|
|
5138
|
+
}
|
|
5139
|
+
|
|
5140
|
+
parent.style.left = ( leftPosition ) + 'px';
|
|
5141
|
+
|
|
5142
|
+
let maxX = window.innerWidth;
|
|
5143
|
+
|
|
5144
|
+
if( overflowContainer )
|
|
5145
|
+
{
|
|
5146
|
+
const parentRect = overflowContainer.getBoundingClientRect();
|
|
5147
|
+
maxX = parentRect.x + parentRect.width;
|
|
5148
|
+
}
|
|
5149
|
+
|
|
5150
|
+
const showLeft = ( leftPosition + listWidth ) > maxX;
|
|
5151
|
+
if( showLeft )
|
|
5152
|
+
{
|
|
5153
|
+
parent.style.left = ( leftPosition - ( listWidth - rect.width ) ) + 'px';
|
|
5154
|
+
}
|
|
4997
5155
|
}
|
|
4998
|
-
return Math.max( maxWidth * 10, 80 );
|
|
4999
5156
|
};
|
|
5000
5157
|
|
|
5001
5158
|
let selectedOption = this.addButton( null, buttonName, ( value, event ) => {
|
|
@@ -5005,52 +5162,50 @@ class Panel {
|
|
|
5005
5162
|
return;
|
|
5006
5163
|
}
|
|
5007
5164
|
|
|
5008
|
-
|
|
5009
|
-
|
|
5165
|
+
listDialog.classList.remove( "place-above" );
|
|
5166
|
+
const opened = listDialog.hasAttribute( "open" );
|
|
5010
5167
|
|
|
5011
|
-
|
|
5012
|
-
const rect = selectedOption.getBoundingClientRect();
|
|
5013
|
-
const topPosition = rect.y;
|
|
5014
|
-
|
|
5015
|
-
let maxY = window.innerHeight;
|
|
5016
|
-
let overflowContainer = list.getParentArea();
|
|
5017
|
-
|
|
5018
|
-
if( overflowContainer )
|
|
5168
|
+
if( !opened )
|
|
5019
5169
|
{
|
|
5020
|
-
|
|
5021
|
-
|
|
5170
|
+
listDialog.show();
|
|
5171
|
+
_placeOptions( listDialog );
|
|
5172
|
+
}
|
|
5173
|
+
else
|
|
5174
|
+
{
|
|
5175
|
+
listDialog.close();
|
|
5022
5176
|
}
|
|
5023
5177
|
|
|
5024
|
-
|
|
5025
|
-
|
|
5026
|
-
const showAbove = ( topPosition + listHeight ) > maxY;
|
|
5027
|
-
if( showAbove )
|
|
5178
|
+
if( filter )
|
|
5028
5179
|
{
|
|
5029
|
-
|
|
5030
|
-
list.classList.add( "place-above" );
|
|
5180
|
+
filter.querySelector( "input" ).focus();
|
|
5031
5181
|
}
|
|
5032
5182
|
|
|
5033
|
-
|
|
5034
|
-
list.style.minWidth = (_getMaxListWidth()) + 'px';
|
|
5035
|
-
list.focus();
|
|
5036
|
-
}, { buttonClass: "array", skipInlineCount: true });
|
|
5183
|
+
}, { buttonClass: "array", skipInlineCount: true, disabled: options.disabled });
|
|
5037
5184
|
|
|
5038
5185
|
this.clearQueue();
|
|
5039
5186
|
|
|
5040
5187
|
selectedOption.style.width = "100%";
|
|
5041
5188
|
|
|
5042
5189
|
selectedOption.refresh = (v) => {
|
|
5043
|
-
if(selectedOption.querySelector("span").innerText == "")
|
|
5190
|
+
if( selectedOption.querySelector("span").innerText == "" )
|
|
5191
|
+
{
|
|
5044
5192
|
selectedOption.querySelector("span").innerText = v;
|
|
5193
|
+
}
|
|
5045
5194
|
else
|
|
5195
|
+
{
|
|
5046
5196
|
selectedOption.querySelector("span").innerHTML = selectedOption.querySelector("span").innerHTML.replaceAll(selectedOption.querySelector("span").innerText, v);
|
|
5197
|
+
}
|
|
5047
5198
|
}
|
|
5048
5199
|
|
|
5049
5200
|
// Add dropdown options container
|
|
5201
|
+
|
|
5202
|
+
const listDialog = document.createElement( 'dialog' );
|
|
5203
|
+
listDialog.className = "lexdropdownoptions";
|
|
5204
|
+
|
|
5050
5205
|
let list = document.createElement( 'ul' );
|
|
5051
5206
|
list.tabIndex = -1;
|
|
5052
5207
|
list.className = "lexoptions";
|
|
5053
|
-
|
|
5208
|
+
listDialog.appendChild( list )
|
|
5054
5209
|
|
|
5055
5210
|
list.addEventListener( 'focusout', function( e ) {
|
|
5056
5211
|
e.stopPropagation();
|
|
@@ -5068,97 +5223,118 @@ class Panel {
|
|
|
5068
5223
|
{
|
|
5069
5224
|
return;
|
|
5070
5225
|
}
|
|
5071
|
-
|
|
5226
|
+
listDialog.close();
|
|
5072
5227
|
});
|
|
5073
5228
|
|
|
5074
5229
|
// Add filter options
|
|
5075
5230
|
let filter = null;
|
|
5076
|
-
if(options.filter ?? false)
|
|
5231
|
+
if( options.filter ?? false )
|
|
5077
5232
|
{
|
|
5078
|
-
filter = this._addFilter("Search
|
|
5079
|
-
}
|
|
5233
|
+
filter = this._addFilter( options.placeholder ?? "Search...", { container: list, callback: this._filterOptions.bind( list, values )} );
|
|
5080
5234
|
|
|
5081
|
-
|
|
5082
|
-
const listOptions = document.createElement('span');
|
|
5083
|
-
list.appendChild( listOptions );
|
|
5084
|
-
|
|
5085
|
-
if( filter )
|
|
5086
|
-
{
|
|
5087
|
-
list.prepend( filter );
|
|
5088
|
-
listOptions.style.height = "calc(100% - 25px)";
|
|
5235
|
+
list.appendChild( filter );
|
|
5089
5236
|
|
|
5090
5237
|
filter.addEventListener('focusout', function( e ) {
|
|
5091
5238
|
if (e.relatedTarget && e.relatedTarget.tagName == "UL" && e.relatedTarget.classList.contains("lexoptions"))
|
|
5092
5239
|
{
|
|
5093
5240
|
return;
|
|
5094
5241
|
}
|
|
5095
|
-
|
|
5242
|
+
listDialog.close();
|
|
5096
5243
|
});
|
|
5097
5244
|
}
|
|
5098
5245
|
|
|
5246
|
+
// Create option list to empty it easily..
|
|
5247
|
+
const listOptions = document.createElement('span');
|
|
5248
|
+
listOptions.style.height = "calc(100% - 25px)";
|
|
5249
|
+
list.appendChild( listOptions );
|
|
5250
|
+
|
|
5099
5251
|
// Add dropdown options list
|
|
5100
|
-
list.refresh = options => {
|
|
5252
|
+
list.refresh = ( options ) => {
|
|
5101
5253
|
|
|
5102
5254
|
// Empty list
|
|
5103
5255
|
listOptions.innerHTML = "";
|
|
5104
5256
|
|
|
5105
|
-
|
|
5257
|
+
if( !options.length )
|
|
5258
|
+
{
|
|
5259
|
+
let iValue = options.emptyMsg ?? "No options found.";
|
|
5260
|
+
|
|
5261
|
+
let option = document.createElement( "div" );
|
|
5262
|
+
option.className = "option";
|
|
5263
|
+
option.style.flexDirection = "unset";
|
|
5264
|
+
option.innerHTML = iValue;
|
|
5265
|
+
|
|
5266
|
+
let li = document.createElement( "li" );
|
|
5267
|
+
li.className = "lexdropdownitem empty";
|
|
5268
|
+
li.appendChild( option );
|
|
5269
|
+
|
|
5270
|
+
listOptions.appendChild( li );
|
|
5271
|
+
return;
|
|
5272
|
+
}
|
|
5273
|
+
|
|
5274
|
+
for( let i = 0; i < options.length; i++ )
|
|
5106
5275
|
{
|
|
5107
|
-
let iValue = options[i];
|
|
5108
|
-
let li = document.createElement(
|
|
5109
|
-
let option = document.createElement(
|
|
5276
|
+
let iValue = options[ i ];
|
|
5277
|
+
let li = document.createElement( "li" );
|
|
5278
|
+
let option = document.createElement( "div" );
|
|
5110
5279
|
option.className = "option";
|
|
5111
|
-
li.appendChild(option);
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
e.currentTarget.
|
|
5118
|
-
e.currentTarget.
|
|
5280
|
+
li.appendChild( option );
|
|
5281
|
+
|
|
5282
|
+
li.addEventListener( "click", e => {
|
|
5283
|
+
listDialog.close();
|
|
5284
|
+
const currentSelected = element.querySelector( ".lexoptions .selected" );
|
|
5285
|
+
if(currentSelected) currentSelected.classList.remove( "selected" );
|
|
5286
|
+
value = e.currentTarget.getAttribute( "value" );
|
|
5287
|
+
e.currentTarget.toggleAttribute( "hidden", false );
|
|
5288
|
+
e.currentTarget.classList.add( "selected" );
|
|
5119
5289
|
selectedOption.refresh(value);
|
|
5120
5290
|
|
|
5121
|
-
let btn = element.querySelector(".lexwidgetname .lexicon");
|
|
5122
|
-
if(btn) btn.style.display = (value != wValue.iValue ? "block" : "none");
|
|
5123
|
-
that._trigger( new IEvent(name, value, null), callback );
|
|
5291
|
+
let btn = element.querySelector( ".lexwidgetname .lexicon" );
|
|
5292
|
+
if( btn ) btn.style.display = (value != wValue.iValue ? "block" : "none");
|
|
5293
|
+
that._trigger( new IEvent( name, value, null ), callback );
|
|
5124
5294
|
|
|
5125
5295
|
// Reset filter
|
|
5126
|
-
if(filter)
|
|
5296
|
+
if( filter )
|
|
5127
5297
|
{
|
|
5128
|
-
filter.querySelector(
|
|
5129
|
-
this.
|
|
5298
|
+
filter.querySelector( "input" ).value = "";
|
|
5299
|
+
this._filterOptions.bind( list, values, "" )();
|
|
5130
5300
|
}
|
|
5131
5301
|
});
|
|
5132
5302
|
|
|
5133
5303
|
// Add string option
|
|
5134
|
-
if( iValue.constructor != Object )
|
|
5135
|
-
|
|
5304
|
+
if( iValue.constructor != Object )
|
|
5305
|
+
{
|
|
5306
|
+
option.style.flexDirection = "unset";
|
|
5136
5307
|
option.innerHTML = "</a><span>" + iValue + "</span><a class='fa-solid fa-check'>";
|
|
5137
5308
|
option.value = iValue;
|
|
5138
|
-
li.setAttribute("value", iValue);
|
|
5309
|
+
li.setAttribute( "value", iValue );
|
|
5139
5310
|
li.className = "lexdropdownitem";
|
|
5140
|
-
|
|
5141
|
-
if(iValue == value)
|
|
5142
|
-
|
|
5311
|
+
|
|
5312
|
+
if( iValue == value )
|
|
5313
|
+
{
|
|
5314
|
+
li.classList.add( "selected" );
|
|
5143
5315
|
wValue.innerHTML = iValue;
|
|
5144
5316
|
}
|
|
5145
5317
|
}
|
|
5146
|
-
else
|
|
5318
|
+
else
|
|
5319
|
+
{
|
|
5147
5320
|
// Add image option
|
|
5148
|
-
let img = document.createElement("img");
|
|
5321
|
+
let img = document.createElement( "img" );
|
|
5149
5322
|
img.src = iValue.src;
|
|
5150
|
-
li.setAttribute("value", iValue.value);
|
|
5323
|
+
li.setAttribute( "value", iValue.value );
|
|
5151
5324
|
li.className = "lexlistitem";
|
|
5152
5325
|
option.innerText = iValue.value;
|
|
5153
5326
|
option.className += " media";
|
|
5154
|
-
option.prepend(img);
|
|
5327
|
+
option.prepend( img );
|
|
5328
|
+
|
|
5329
|
+
option.setAttribute( "value", iValue.value );
|
|
5330
|
+
option.setAttribute( "data-index", i );
|
|
5331
|
+
option.setAttribute( "data-src", iValue.src );
|
|
5332
|
+
option.setAttribute( "title", iValue.value );
|
|
5155
5333
|
|
|
5156
|
-
|
|
5157
|
-
|
|
5158
|
-
|
|
5159
|
-
|
|
5160
|
-
if(value == iValue.value)
|
|
5161
|
-
li.classList.add("selected");
|
|
5334
|
+
if( value == iValue.value )
|
|
5335
|
+
{
|
|
5336
|
+
li.classList.add( "selected" );
|
|
5337
|
+
}
|
|
5162
5338
|
}
|
|
5163
5339
|
|
|
5164
5340
|
listOptions.appendChild( li );
|
|
@@ -5167,7 +5343,7 @@ class Panel {
|
|
|
5167
5343
|
|
|
5168
5344
|
list.refresh( values );
|
|
5169
5345
|
|
|
5170
|
-
container.appendChild(
|
|
5346
|
+
container.appendChild( listDialog );
|
|
5171
5347
|
element.appendChild( container );
|
|
5172
5348
|
|
|
5173
5349
|
// Remove branch padding and margins
|
|
@@ -7346,6 +7522,228 @@ class Panel {
|
|
|
7346
7522
|
|
|
7347
7523
|
return widget;
|
|
7348
7524
|
}
|
|
7525
|
+
|
|
7526
|
+
/**
|
|
7527
|
+
* @method addTable
|
|
7528
|
+
* @param {String} name Widget name
|
|
7529
|
+
* @param {Number} data Table data
|
|
7530
|
+
* @param {*} options:
|
|
7531
|
+
* head: Table headers (each of the headers per column)
|
|
7532
|
+
* body: Table body (data per row for each column)
|
|
7533
|
+
* rowActions: Allow to add actions per row
|
|
7534
|
+
* onMenuAction: Function callback to fill the "menu" context
|
|
7535
|
+
* selectable: Each row can be selected
|
|
7536
|
+
*/
|
|
7537
|
+
|
|
7538
|
+
addTable( name, data, options = { } ) {
|
|
7539
|
+
|
|
7540
|
+
if( !data )
|
|
7541
|
+
{
|
|
7542
|
+
throw( "Data is needed to create a table!" );
|
|
7543
|
+
}
|
|
7544
|
+
|
|
7545
|
+
let widget = this.create_widget( name, Widget.TABLE, options );
|
|
7546
|
+
|
|
7547
|
+
widget.onGetValue = () => {
|
|
7548
|
+
|
|
7549
|
+
};
|
|
7550
|
+
|
|
7551
|
+
widget.onSetValue = ( newValue, skipCallback ) => {
|
|
7552
|
+
|
|
7553
|
+
};
|
|
7554
|
+
|
|
7555
|
+
let element = widget.domEl;
|
|
7556
|
+
|
|
7557
|
+
const container = document.createElement('div');
|
|
7558
|
+
container.className = "lextable";
|
|
7559
|
+
container.style.width = "calc( 100% - " + LX.DEFAULT_NAME_WIDTH + ")";
|
|
7560
|
+
|
|
7561
|
+
const table = document.createElement( 'table' );
|
|
7562
|
+
container.appendChild( table );
|
|
7563
|
+
|
|
7564
|
+
data.head = data.head ?? [];
|
|
7565
|
+
data.body = data.body ?? [];
|
|
7566
|
+
data.orderMap = { };
|
|
7567
|
+
data.checkMap = { };
|
|
7568
|
+
|
|
7569
|
+
function compareFn( idx, order, a, b) {
|
|
7570
|
+
if (a[idx] < b[idx]) return -order;
|
|
7571
|
+
else if (a[idx] > b[idx]) return order;
|
|
7572
|
+
return 0;
|
|
7573
|
+
}
|
|
7574
|
+
|
|
7575
|
+
widget.refreshTable = () => {
|
|
7576
|
+
|
|
7577
|
+
table.innerHTML = "";
|
|
7578
|
+
|
|
7579
|
+
// Head
|
|
7580
|
+
{
|
|
7581
|
+
const head = document.createElement( 'thead' );
|
|
7582
|
+
head.className = "lextablehead";
|
|
7583
|
+
table.appendChild( head );
|
|
7584
|
+
|
|
7585
|
+
const hrow = document.createElement( 'tr' );
|
|
7586
|
+
|
|
7587
|
+
if( options.selectable )
|
|
7588
|
+
{
|
|
7589
|
+
const th = document.createElement( 'th' );
|
|
7590
|
+
const input = document.createElement( 'input' );
|
|
7591
|
+
input.type = "checkbox";
|
|
7592
|
+
input.className = "lexcheckbox";
|
|
7593
|
+
input.checked = data.checkMap[ ":root" ] ?? false;
|
|
7594
|
+
th.appendChild( input );
|
|
7595
|
+
|
|
7596
|
+
input.addEventListener( 'change', function() {
|
|
7597
|
+
|
|
7598
|
+
data.checkMap[ ":root" ] = this.checked;
|
|
7599
|
+
|
|
7600
|
+
const body = table.querySelector( "tbody" );
|
|
7601
|
+
for( const el of body.childNodes )
|
|
7602
|
+
{
|
|
7603
|
+
data.checkMap[ el.getAttribute( "rowId" ) ] = this.checked;
|
|
7604
|
+
el.querySelector( "input" ).checked = this.checked;
|
|
7605
|
+
}
|
|
7606
|
+
});
|
|
7607
|
+
|
|
7608
|
+
hrow.appendChild( th );
|
|
7609
|
+
}
|
|
7610
|
+
|
|
7611
|
+
for( const headData of data.head )
|
|
7612
|
+
{
|
|
7613
|
+
const th = document.createElement( 'th' );
|
|
7614
|
+
th.innerHTML = `${ headData } <a class="fa-solid fa-sort"></a>`;
|
|
7615
|
+
|
|
7616
|
+
th.querySelector( 'a' ).addEventListener( 'click', () => {
|
|
7617
|
+
|
|
7618
|
+
if( !data.orderMap[ headData ] )
|
|
7619
|
+
{
|
|
7620
|
+
data.orderMap[ headData ] = 1;
|
|
7621
|
+
}
|
|
7622
|
+
|
|
7623
|
+
const idx = data.head.indexOf(headData);
|
|
7624
|
+
data.body = data.body.sort( compareFn.bind( this, idx,data.orderMap[ headData ] ) );
|
|
7625
|
+
data.orderMap[ headData ] = -data.orderMap[ headData ];
|
|
7626
|
+
|
|
7627
|
+
widget.refreshTable();
|
|
7628
|
+
|
|
7629
|
+
});
|
|
7630
|
+
|
|
7631
|
+
hrow.appendChild( th );
|
|
7632
|
+
}
|
|
7633
|
+
|
|
7634
|
+
// Add empty header column
|
|
7635
|
+
if( options.rowActions )
|
|
7636
|
+
{
|
|
7637
|
+
const th = document.createElement( 'th' );
|
|
7638
|
+
th.className = "sm";
|
|
7639
|
+
hrow.appendChild( th );
|
|
7640
|
+
}
|
|
7641
|
+
|
|
7642
|
+
head.appendChild( hrow );
|
|
7643
|
+
}
|
|
7644
|
+
|
|
7645
|
+
// Body
|
|
7646
|
+
{
|
|
7647
|
+
const body = document.createElement( 'tbody' );
|
|
7648
|
+
body.className = "lextablebody";
|
|
7649
|
+
table.appendChild( body );
|
|
7650
|
+
|
|
7651
|
+
for( let r = 0; r < data.body.length; ++r )
|
|
7652
|
+
{
|
|
7653
|
+
const bodyData = data.body[ r ];
|
|
7654
|
+
const row = document.createElement( 'tr' );
|
|
7655
|
+
const rowId = LX.getSupportedDOMName( bodyData.join( '-' ) );
|
|
7656
|
+
row.setAttribute( "rowId", rowId );
|
|
7657
|
+
|
|
7658
|
+
if( options.selectable )
|
|
7659
|
+
{
|
|
7660
|
+
const td = document.createElement( 'td' );
|
|
7661
|
+
const input = document.createElement( 'input' );
|
|
7662
|
+
input.type = "checkbox";
|
|
7663
|
+
input.className = "lexcheckbox";
|
|
7664
|
+
input.checked = data.checkMap[ rowId ];
|
|
7665
|
+
td.appendChild( input );
|
|
7666
|
+
|
|
7667
|
+
input.addEventListener( 'change', function() {
|
|
7668
|
+
data.checkMap[ rowId ] = this.checked;
|
|
7669
|
+
});
|
|
7670
|
+
|
|
7671
|
+
row.appendChild( td );
|
|
7672
|
+
}
|
|
7673
|
+
|
|
7674
|
+
for( const rowData of bodyData )
|
|
7675
|
+
{
|
|
7676
|
+
const td = document.createElement( 'td' );
|
|
7677
|
+
td.innerHTML = `${ rowData }`;
|
|
7678
|
+
row.appendChild( td );
|
|
7679
|
+
}
|
|
7680
|
+
|
|
7681
|
+
if( options.rowActions )
|
|
7682
|
+
{
|
|
7683
|
+
const td = document.createElement( 'td' );
|
|
7684
|
+
td.className = "sm";
|
|
7685
|
+
|
|
7686
|
+
const buttons = document.createElement( 'div' );
|
|
7687
|
+
buttons.className = "lextablebuttons";
|
|
7688
|
+
td.appendChild( buttons );
|
|
7689
|
+
|
|
7690
|
+
for( const action of options.rowActions )
|
|
7691
|
+
{
|
|
7692
|
+
const button = document.createElement( 'a' );
|
|
7693
|
+
button.className = "lexicon";
|
|
7694
|
+
|
|
7695
|
+
if( action == "delete" )
|
|
7696
|
+
{
|
|
7697
|
+
button.className += " fa-solid fa-trash-can";
|
|
7698
|
+
button.addEventListener( 'click', function() {
|
|
7699
|
+
// Don't need to refresh table..
|
|
7700
|
+
data.body.splice( r, 1 );
|
|
7701
|
+
row.remove();
|
|
7702
|
+
});
|
|
7703
|
+
}
|
|
7704
|
+
else if( action == "menu" )
|
|
7705
|
+
{
|
|
7706
|
+
button.className += " fa-solid fa-ellipsis";
|
|
7707
|
+
button.addEventListener( 'click', function( event ) {
|
|
7708
|
+
addContextMenu( null, event, c => {
|
|
7709
|
+
if( options.onMenuAction )
|
|
7710
|
+
{
|
|
7711
|
+
options.onMenuAction( c );
|
|
7712
|
+
return;
|
|
7713
|
+
}
|
|
7714
|
+
console.warn( "Using <Menu action> without action callbacks." );
|
|
7715
|
+
} );
|
|
7716
|
+
});
|
|
7717
|
+
}
|
|
7718
|
+
else // custom actions
|
|
7719
|
+
{
|
|
7720
|
+
console.assert( action.constructor == Object );
|
|
7721
|
+
button.className += ` ${ action.icon }`;
|
|
7722
|
+
}
|
|
7723
|
+
|
|
7724
|
+
buttons.appendChild( button );
|
|
7725
|
+
}
|
|
7726
|
+
|
|
7727
|
+
row.appendChild( td );
|
|
7728
|
+
}
|
|
7729
|
+
|
|
7730
|
+
body.appendChild( row );
|
|
7731
|
+
}
|
|
7732
|
+
}
|
|
7733
|
+
}
|
|
7734
|
+
|
|
7735
|
+
widget.refreshTable();
|
|
7736
|
+
|
|
7737
|
+
if( !widget.name )
|
|
7738
|
+
{
|
|
7739
|
+
element.className += " noname";
|
|
7740
|
+
container.style.width = "100%";
|
|
7741
|
+
}
|
|
7742
|
+
|
|
7743
|
+
element.appendChild( container );
|
|
7744
|
+
|
|
7745
|
+
return widget;
|
|
7746
|
+
}
|
|
7349
7747
|
}
|
|
7350
7748
|
|
|
7351
7749
|
LX.Panel = Panel;
|
|
@@ -7702,16 +8100,15 @@ class Dialog {
|
|
|
7702
8100
|
draggable = options.draggable ?? true,
|
|
7703
8101
|
modal = options.modal ?? false;
|
|
7704
8102
|
|
|
7705
|
-
|
|
7706
|
-
{
|
|
7707
|
-
LX.modal.toggle( false );
|
|
7708
|
-
}
|
|
7709
|
-
|
|
7710
|
-
var root = document.createElement('div');
|
|
8103
|
+
var root = document.createElement('dialog');
|
|
7711
8104
|
root.className = "lexdialog " + (options.class ?? "");
|
|
7712
8105
|
root.id = options.id ?? "dialog" + Dialog._last_id++;
|
|
7713
8106
|
LX.root.appendChild( root );
|
|
7714
8107
|
|
|
8108
|
+
doAsync( () => {
|
|
8109
|
+
modal ? root.showModal() : root.show();
|
|
8110
|
+
}, 10 );
|
|
8111
|
+
|
|
7715
8112
|
let that = this;
|
|
7716
8113
|
|
|
7717
8114
|
var titleDiv = document.createElement('div');
|
|
@@ -7793,18 +8190,17 @@ class Dialog {
|
|
|
7793
8190
|
|
|
7794
8191
|
if( !options.onclose )
|
|
7795
8192
|
{
|
|
7796
|
-
|
|
7797
|
-
|
|
8193
|
+
root.close();
|
|
8194
|
+
|
|
8195
|
+
doAsync( () => {
|
|
8196
|
+
that.panel.clear();
|
|
8197
|
+
root.remove();
|
|
8198
|
+
}, 150 );
|
|
7798
8199
|
}
|
|
7799
8200
|
else
|
|
7800
8201
|
{
|
|
7801
8202
|
options.onclose( this.root );
|
|
7802
8203
|
}
|
|
7803
|
-
|
|
7804
|
-
if( modal )
|
|
7805
|
-
{
|
|
7806
|
-
LX.modal.toggle( true );
|
|
7807
|
-
}
|
|
7808
8204
|
};
|
|
7809
8205
|
|
|
7810
8206
|
var closeButton = document.createElement( 'a' );
|
|
@@ -7919,21 +8315,29 @@ class PocketDialog extends Dialog {
|
|
|
7919
8315
|
options.draggable = options.draggable ?? false;
|
|
7920
8316
|
options.closable = options.closable ?? false;
|
|
7921
8317
|
|
|
8318
|
+
const dragMargin = 3;
|
|
8319
|
+
|
|
7922
8320
|
super( title, callback, options );
|
|
7923
8321
|
|
|
7924
8322
|
let that = this;
|
|
7925
8323
|
// Update margins on branch title closes/opens
|
|
7926
8324
|
LX.addSignal("@on_branch_closed", this.panel, closed => {
|
|
7927
8325
|
if( this.dock_pos == PocketDialog.BOTTOM )
|
|
7928
|
-
|
|
8326
|
+
{
|
|
8327
|
+
this.root.style.top = "calc(100% - " + (this.root.offsetHeight + dragMargin) + "px)";
|
|
8328
|
+
}
|
|
7929
8329
|
});
|
|
7930
8330
|
|
|
7931
8331
|
// Custom
|
|
7932
8332
|
this.root.classList.add( "pocket" );
|
|
7933
|
-
|
|
7934
|
-
|
|
7935
|
-
|
|
8333
|
+
this.root.style.left = "unset";
|
|
8334
|
+
|
|
8335
|
+
if( !options.position )
|
|
8336
|
+
{
|
|
8337
|
+
this.root.style.right = dragMargin + "px";
|
|
8338
|
+
this.root.style.top = dragMargin + "px";
|
|
7936
8339
|
}
|
|
8340
|
+
|
|
7937
8341
|
this.panel.root.style.width = "calc( 100% - 12px )";
|
|
7938
8342
|
this.panel.root.style.height = "calc( 100% - 40px )";
|
|
7939
8343
|
this.dock_pos = PocketDialog.TOP;
|
|
@@ -7954,7 +8358,7 @@ class PocketDialog extends Dialog {
|
|
|
7954
8358
|
|
|
7955
8359
|
if( this.dock_pos == PocketDialog.BOTTOM )
|
|
7956
8360
|
that.root.style.top = this.root.classList.contains("minimized") ?
|
|
7957
|
-
"calc(100% - " + (that.title.offsetHeight + 6) + "px)" : "calc(100% - " + (that.root.offsetHeight +
|
|
8361
|
+
"calc(100% - " + (that.title.offsetHeight + 6) + "px)" : "calc(100% - " + (that.root.offsetHeight + dragMargin) + "px)";
|
|
7958
8362
|
});
|
|
7959
8363
|
|
|
7960
8364
|
if( !options.draggable )
|
|
@@ -7969,26 +8373,42 @@ class PocketDialog extends Dialog {
|
|
|
7969
8373
|
switch( t )
|
|
7970
8374
|
{
|
|
7971
8375
|
case 'b':
|
|
7972
|
-
this.root.style.top = "calc(100% - " + (this.root.offsetHeight +
|
|
8376
|
+
this.root.style.top = "calc(100% - " + (this.root.offsetHeight + dragMargin) + "px)";
|
|
7973
8377
|
break;
|
|
7974
8378
|
case 'l':
|
|
7975
|
-
this.root.style.
|
|
8379
|
+
this.root.style.right = "unset";
|
|
8380
|
+
this.root.style.left = options.position ? options.position[ 1 ] : ( dragMargin + "px" );
|
|
7976
8381
|
break;
|
|
7977
8382
|
}
|
|
7978
8383
|
}
|
|
7979
8384
|
}
|
|
7980
8385
|
|
|
7981
8386
|
this.root.classList.add('dockable');
|
|
7982
|
-
|
|
7983
|
-
|
|
8387
|
+
|
|
8388
|
+
this.title.addEventListener("keydown", function( e ) {
|
|
8389
|
+
if( !e.ctrlKey )
|
|
8390
|
+
{
|
|
8391
|
+
return;
|
|
8392
|
+
}
|
|
8393
|
+
|
|
8394
|
+
that.root.style.right = "unset";
|
|
8395
|
+
|
|
8396
|
+
if( e.key == 'ArrowLeft' )
|
|
8397
|
+
{
|
|
7984
8398
|
that.root.style.left = '0px';
|
|
7985
|
-
}
|
|
7986
|
-
|
|
7987
|
-
|
|
8399
|
+
}
|
|
8400
|
+
else if( e.key == 'ArrowRight' )
|
|
8401
|
+
{
|
|
8402
|
+
that.root.style.left = "calc(100% - " + (that.root.offsetWidth + dragMargin) + "px)";
|
|
8403
|
+
}
|
|
8404
|
+
else if( e.key == 'ArrowUp' )
|
|
8405
|
+
{
|
|
7988
8406
|
that.root.style.top = "0px";
|
|
7989
8407
|
that.dock_pos = PocketDialog.TOP;
|
|
7990
|
-
}
|
|
7991
|
-
|
|
8408
|
+
}
|
|
8409
|
+
else if( e.key == 'ArrowDown' )
|
|
8410
|
+
{
|
|
8411
|
+
that.root.style.top = "calc(100% - " + (that.root.offsetHeight + dragMargin) + "px)";
|
|
7992
8412
|
that.dock_pos = PocketDialog.BOTTOM;
|
|
7993
8413
|
}
|
|
7994
8414
|
});
|
|
@@ -9287,7 +9707,7 @@ class AssetView {
|
|
|
9287
9707
|
}
|
|
9288
9708
|
|
|
9289
9709
|
this.rightPanel.sameLine();
|
|
9290
|
-
this.rightPanel.addDropdown( "Filter", this.allowedTypes, this.allowedTypes[ 0 ], v => this._refreshContent.call(this, null, v), { width: "
|
|
9710
|
+
this.rightPanel.addDropdown( "Filter", this.allowedTypes, this.allowedTypes[ 0 ], v => this._refreshContent.call(this, null, v), { width: "30%", minWidth: "128px" } );
|
|
9291
9711
|
this.rightPanel.addText( null, this.searchValue ?? "", v => this._refreshContent.call(this, v, null), { placeholder: "Search assets.." } );
|
|
9292
9712
|
this.rightPanel.addButton( null, "<a class='fa fa-arrow-up-short-wide'></a>", on_sort.bind(this), { className: "micro", title: "Sort" } );
|
|
9293
9713
|
this.rightPanel.addButton( null, "<a class='fa-solid fa-grip'></a>", on_change_view.bind(this), { className: "micro", title: "View" } );
|