lexgui 0.1.41 → 0.1.42

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.41",
11
+ version: "0.1.42",
12
12
  ready: false,
13
13
  components: [], // specific pre-build components
14
14
  signals: {} // events and triggers
@@ -498,7 +498,7 @@ function create_global_searchbar( root ) {
498
498
  * @param {Object} options
499
499
  * container: Root location for the gui (default is the document body)
500
500
  * id: Id of the main area
501
- * skip_default_area: Skip creation of main area
501
+ * skipDefaultArea: Skip creation of main area
502
502
  */
503
503
 
504
504
  function init( options = { } )
@@ -555,8 +555,10 @@ function init( options = { } )
555
555
  this.ready = true;
556
556
  this.menubars = [ ];
557
557
 
558
- if( !options.skip_default_area )
558
+ if( !options.skipDefaultArea )
559
+ {
559
560
  this.main_area = new Area( { id: options.id ?? 'mainarea' } );
561
+ }
560
562
 
561
563
  return this.main_area;
562
564
  }
@@ -573,16 +575,18 @@ LX.init = init;
573
575
  * draggable: Dialog can be dragged [false]
574
576
  */
575
577
 
576
- function message(text, title, options = {})
578
+ function message( text, title, options = {} )
577
579
  {
578
- if(!text)
579
- throw("No message to show");
580
+ if( !text )
581
+ {
582
+ throw( "No message to show" );
583
+ }
580
584
 
581
585
  options.modal = true;
582
586
 
583
- return new Dialog(title, p => {
584
- p.addTextArea(null, text, null, { disabled: true, fitHeight: true });
585
- }, options);
587
+ return new Dialog( title, p => {
588
+ p.addTextArea( null, text, null, { disabled: true, fitHeight: true } );
589
+ }, options );
586
590
  }
587
591
 
588
592
  LX.message = message;
@@ -662,7 +666,8 @@ function prompt( text, title, callback, options = {} )
662
666
  text += text.includes("You must fill the input text.") ? "": "\nYou must fill the input text.";
663
667
  dialog.close();
664
668
  prompt( text, title, callback, options );
665
- }else
669
+ }
670
+ else
666
671
  {
667
672
  if( callback ) callback.call( this, value );
668
673
  dialog.close();
@@ -742,7 +747,9 @@ function emit( signalName, value, options = {} )
742
747
  const data = LX.signals[ signalName ];
743
748
 
744
749
  if( !data )
745
- return;
750
+ {
751
+ return;
752
+ }
746
753
 
747
754
  const target = options.target;
748
755
 
@@ -781,10 +788,14 @@ function addSignal( name, obj, callback )
781
788
  obj[name] = callback;
782
789
 
783
790
  if( !LX.signals[ name ] )
791
+ {
784
792
  LX.signals[ name ] = [];
793
+ }
785
794
 
786
795
  if( LX.signals[ name ].indexOf( obj ) > -1 )
796
+ {
787
797
  return;
798
+ }
788
799
 
789
800
  LX.signals[ name ].push( obj );
790
801
  }
@@ -804,7 +815,7 @@ class Area {
804
815
  * className: Add class to the element
805
816
  * width: Width of the area element [fit space]
806
817
  * height: Height of the area element [fit space]
807
- * no_append: Create but not append to GUI root [false]
818
+ * skipAppend: Create but not append to GUI root [false]
808
819
  */
809
820
 
810
821
  constructor( options = {} ) {
@@ -844,7 +855,7 @@ class Area {
844
855
  this.sections = [];
845
856
  this.panels = [];
846
857
 
847
- if( !options.no_append )
858
+ if( !options.skipAppend )
848
859
  {
849
860
  var lexroot = document.getElementById("lexroot");
850
861
  lexroot.appendChild( this.root );
@@ -879,94 +890,97 @@ class Area {
879
890
  makeDraggable( root, options );
880
891
  }
881
892
 
882
- if( options.resizeable ) {
893
+ if( options.resizeable )
894
+ {
883
895
  root.classList.add("resizeable");
884
896
  }
885
897
 
886
898
  if( options.resize )
887
899
  {
888
- this.split_bar = document.createElement("div");
900
+ this.splitBar = document.createElement("div");
889
901
  let type = (overlay == "left") || (overlay == "right") ? "horizontal" : "vertical";
890
- this.type = overlay;;
891
- this.split_bar.className = "lexsplitbar " + type;
902
+ this.type = overlay;
903
+ this.splitBar.className = "lexsplitbar " + type;
892
904
 
893
905
  if( overlay == "right" )
894
906
  {
895
- this.split_bar.style.width = LX.DEFAULT_SPLITBAR_SIZE + "px";
896
- this.split_bar.style.left = -(LX.DEFAULT_SPLITBAR_SIZE / 2.0) + "px";
907
+ this.splitBar.style.width = LX.DEFAULT_SPLITBAR_SIZE + "px";
908
+ this.splitBar.style.left = -(LX.DEFAULT_SPLITBAR_SIZE / 2.0) + "px";
897
909
  }
898
910
  else if( overlay == "left" )
899
911
  {
900
912
  let size = Math.min(document.body.clientWidth - LX.DEFAULT_SPLITBAR_SIZE, this.root.clientWidth);
901
- this.split_bar.style.width = LX.DEFAULT_SPLITBAR_SIZE + "px";
902
- this.split_bar.style.left = size + (LX.DEFAULT_SPLITBAR_SIZE / 2.0) + "px";
913
+ this.splitBar.style.width = LX.DEFAULT_SPLITBAR_SIZE + "px";
914
+ this.splitBar.style.left = size + (LX.DEFAULT_SPLITBAR_SIZE / 2.0) + "px";
903
915
  }
904
916
  else if( overlay == "top" )
905
917
  {
906
918
  let size = Math.min(document.body.clientHeight - LX.DEFAULT_SPLITBAR_SIZE, this.root.clientHeight);
907
- this.split_bar.style.height = LX.DEFAULT_SPLITBAR_SIZE + "px";
908
- this.split_bar.style.top = size + (LX.DEFAULT_SPLITBAR_SIZE / 2.0) + "px";
919
+ this.splitBar.style.height = LX.DEFAULT_SPLITBAR_SIZE + "px";
920
+ this.splitBar.style.top = size + (LX.DEFAULT_SPLITBAR_SIZE / 2.0) + "px";
909
921
  }
910
922
  else if( overlay == "bottom" )
911
923
  {
912
- this.split_bar.style.height = LX.DEFAULT_SPLITBAR_SIZE + "px";
913
- this.split_bar.style.top = -(LX.DEFAULT_SPLITBAR_SIZE / 2.0) + "px";
924
+ this.splitBar.style.height = LX.DEFAULT_SPLITBAR_SIZE + "px";
925
+ this.splitBar.style.top = -(LX.DEFAULT_SPLITBAR_SIZE / 2.0) + "px";
914
926
  }
915
927
 
916
- this.split_bar.addEventListener("mousedown", inner_mousedown);
917
- this.root.appendChild( this.split_bar );
928
+ this.splitBar.addEventListener("mousedown", inner_mousedown);
929
+ this.root.appendChild( this.splitBar );
918
930
 
919
931
  var that = this;
920
- var last_pos = [ 0, 0 ];
932
+ var lastMousePosition = [ 0, 0 ];
921
933
 
922
934
  function inner_mousedown( e )
923
935
  {
924
936
  var doc = that.root.ownerDocument;
925
937
  doc.addEventListener( 'mousemove', inner_mousemove );
926
938
  doc.addEventListener( 'mouseup', inner_mouseup );
927
- last_pos[ 0 ] = e.x;
928
- last_pos[ 1 ] = e.y;
939
+ lastMousePosition[ 0 ] = e.x;
940
+ lastMousePosition[ 1 ] = e.y;
929
941
  e.stopPropagation();
930
942
  e.preventDefault();
931
943
  document.body.classList.add( 'nocursor' );
932
- that.split_bar.classList.add( 'nocursor' );
944
+ that.splitBar.classList.add( 'nocursor' );
933
945
  }
934
946
 
935
947
  function inner_mousemove( e )
936
948
  {
937
949
  switch( that.type ) {
938
950
  case "right":
939
- var dt = ( last_pos[ 0 ] - e.x );
951
+ var dt = ( lastMousePosition[ 0 ] - e.x );
940
952
  var size = ( that.root.offsetWidth + dt );
941
953
  that.root.style.width = size + "px";
942
954
  break;
943
955
  case "left":
944
- var dt = ( last_pos[ 0 ] - e.x );
956
+ var dt = ( lastMousePosition[ 0 ] - e.x );
945
957
  var size = Math.min(document.body.clientWidth - LX.DEFAULT_SPLITBAR_SIZE, (that.root.offsetWidth - dt));
946
958
  that.root.style.width = size + "px";
947
- that.split_bar.style.left = size + LX.DEFAULT_SPLITBAR_SIZE/2 + "px";
959
+ that.splitBar.style.left = size + LX.DEFAULT_SPLITBAR_SIZE/2 + "px";
948
960
  break;
949
961
  case "top":
950
- var dt = ( last_pos[ 1 ] - e.y );
962
+ var dt = ( lastMousePosition[ 1 ] - e.y );
951
963
  var size = Math.min(document.body.clientHeight - LX.DEFAULT_SPLITBAR_SIZE, (that.root.offsetHeight - dt));
952
964
  that.root.style.height = size + "px";
953
- that.split_bar.style.top = size + LX.DEFAULT_SPLITBAR_SIZE/2 + "px";
965
+ that.splitBar.style.top = size + LX.DEFAULT_SPLITBAR_SIZE/2 + "px";
954
966
  break;
955
967
  case "bottom":
956
- var dt = ( last_pos[ 1 ] - e.y );
968
+ var dt = ( lastMousePosition[ 1 ] - e.y );
957
969
  var size = ( that.root.offsetHeight + dt );
958
970
  that.root.style.height = size + "px";
959
971
  break;
960
972
  }
961
973
 
962
- last_pos[ 0 ] = e.x;
963
- last_pos[ 1 ] = e.y;
974
+ lastMousePosition[ 0 ] = e.x;
975
+ lastMousePosition[ 1 ] = e.y;
964
976
  e.stopPropagation();
965
977
  e.preventDefault();
966
978
 
967
979
  // Resize events
968
980
  if( that.onresize )
981
+ {
969
982
  that.onresize( that.root.getBoundingClientRect() );
983
+ }
970
984
  }
971
985
 
972
986
  function inner_mouseup( e )
@@ -975,7 +989,7 @@ class Area {
975
989
  doc.removeEventListener( 'mousemove', inner_mousemove );
976
990
  doc.removeEventListener( 'mouseup', inner_mouseup );
977
991
  document.body.classList.remove( 'nocursor' );
978
- that.split_bar.classList.remove( 'nocursor' );
992
+ that.splitBar.classList.remove( 'nocursor' );
979
993
  }
980
994
  }
981
995
  }
@@ -989,13 +1003,16 @@ class Area {
989
1003
  attach( content ) {
990
1004
 
991
1005
  // Append to last split section if area has been split
992
- if(this.sections.length) {
993
- this.sections[1].attach( content );
1006
+ if( this.sections.length)
1007
+ {
1008
+ this.sections[ 1 ].attach( content );
994
1009
  return;
995
1010
  }
996
1011
 
997
- if(!content)
998
- throw("no content to attach");
1012
+ if( !content )
1013
+ {
1014
+ throw("no content to attach");
1015
+ }
999
1016
 
1000
1017
  content.parent = this;
1001
1018
 
@@ -1040,14 +1057,14 @@ class Area {
1040
1057
  }
1041
1058
 
1042
1059
  // Create areas
1043
- var area1 = new Area( { no_append: true, className: "split" + ( options.menubar || options.sidebar ? "" : " origin" ) } );
1044
- var area2 = new Area( { no_append: true, className: "split"} );
1060
+ var area1 = new Area( { skipAppend: true, className: "split" + ( options.menubar || options.sidebar ? "" : " origin" ) } );
1061
+ var area2 = new Area( { skipAppend: true, className: "split" } );
1045
1062
 
1046
1063
  area1.parentArea = this;
1047
1064
  area2.parentArea = this;
1048
1065
 
1049
1066
  let minimizable = options.minimizable ?? false;
1050
- let resize = (options.resize ?? true) || minimizable;
1067
+ let resize = ( options.resize ?? true ) || minimizable;
1051
1068
 
1052
1069
  var data = "0px";
1053
1070
  this.offset = 0;
@@ -1055,19 +1072,19 @@ class Area {
1055
1072
  if( resize )
1056
1073
  {
1057
1074
  this.resize = resize;
1058
- this.split_bar = document.createElement( "div" );
1059
- this.split_bar.className = "lexsplitbar " + type;
1075
+ this.splitBar = document.createElement( "div" );
1076
+ this.splitBar.className = "lexsplitbar " + type;
1060
1077
 
1061
1078
  if( type == "horizontal" )
1062
1079
  {
1063
- this.split_bar.style.width = LX.DEFAULT_SPLITBAR_SIZE + "px";
1080
+ this.splitBar.style.width = LX.DEFAULT_SPLITBAR_SIZE + "px";
1064
1081
  }
1065
1082
  else
1066
1083
  {
1067
- this.split_bar.style.height = LX.DEFAULT_SPLITBAR_SIZE + "px";
1084
+ this.splitBar.style.height = LX.DEFAULT_SPLITBAR_SIZE + "px";
1068
1085
  }
1069
1086
 
1070
- this.split_bar.addEventListener( 'mousedown', inner_mousedown );
1087
+ this.splitBar.addEventListener( 'mousedown', inner_mousedown );
1071
1088
 
1072
1089
  data = ( LX.DEFAULT_SPLITBAR_SIZE / 2 ) + "px"; // updates
1073
1090
 
@@ -1084,7 +1101,7 @@ class Area {
1084
1101
  flushCss(area2.root);
1085
1102
  });
1086
1103
 
1087
- this.split_bar.addEventListener("contextmenu", e => {
1104
+ this.splitBar.addEventListener("contextmenu", e => {
1088
1105
  e.preventDefault();
1089
1106
  addContextMenu(null, e, c => {
1090
1107
  c.add("Extend", { disabled: this.split_extended, callback: () => { this.extend() } });
@@ -1115,7 +1132,7 @@ class Area {
1115
1132
  area1.root.style.width = "100%";
1116
1133
  area2.root.style.width = "100%";
1117
1134
 
1118
- if(auto)
1135
+ if( auto )
1119
1136
  {
1120
1137
  area1.root.style.height = "auto";
1121
1138
 
@@ -1149,11 +1166,11 @@ class Area {
1149
1166
 
1150
1167
  if( resize )
1151
1168
  {
1152
- this.root.appendChild(this.split_bar);
1169
+ this.root.appendChild(this.splitBar);
1153
1170
  }
1154
1171
 
1155
1172
  this.root.appendChild( area2.root );
1156
- this.sections = [area1, area2];
1173
+ this.sections = [ area1, area2 ];
1157
1174
  this.type = type;
1158
1175
 
1159
1176
  // Update sizes
@@ -1165,34 +1182,34 @@ class Area {
1165
1182
  }
1166
1183
 
1167
1184
  var that = this;
1168
- var last_pos = [ 0, 0 ];
1185
+ var lastMousePosition = [ 0, 0 ];
1169
1186
 
1170
1187
  function inner_mousedown( e )
1171
1188
  {
1172
1189
  var doc = that.root.ownerDocument;
1173
1190
  doc.addEventListener( 'mousemove', inner_mousemove );
1174
1191
  doc.addEventListener( 'mouseup', inner_mouseup );
1175
- last_pos[0] = e.x;
1176
- last_pos[1] = e.y;
1192
+ lastMousePosition[0] = e.x;
1193
+ lastMousePosition[1] = e.y;
1177
1194
  e.stopPropagation();
1178
1195
  e.preventDefault();
1179
1196
  document.body.classList.add( 'nocursor' );
1180
- that.split_bar.classList.add( 'nocursor' );
1197
+ that.splitBar.classList.add( 'nocursor' );
1181
1198
  }
1182
1199
 
1183
1200
  function inner_mousemove( e )
1184
1201
  {
1185
1202
  if(that.type == "horizontal")
1186
1203
  {
1187
- that._moveSplit( last_pos[ 0 ] - e.x );
1204
+ that._moveSplit( lastMousePosition[ 0 ] - e.x );
1188
1205
  }
1189
1206
  else
1190
1207
  {
1191
- that._moveSplit( last_pos[ 1 ] - e.y );
1208
+ that._moveSplit( lastMousePosition[ 1 ] - e.y );
1192
1209
  }
1193
1210
 
1194
- last_pos[ 0 ] = e.x;
1195
- last_pos[ 1 ] = e.y;
1211
+ lastMousePosition[ 0 ] = e.x;
1212
+ lastMousePosition[ 1 ] = e.y;
1196
1213
 
1197
1214
  const widgets = that.root.querySelectorAll( ".lexwidget" );
1198
1215
 
@@ -1217,7 +1234,7 @@ class Area {
1217
1234
  doc.removeEventListener( 'mousemove', inner_mousemove );
1218
1235
  doc.removeEventListener( 'mouseup', inner_mouseup );
1219
1236
  document.body.classList.remove( 'nocursor' );
1220
- that.split_bar.classList.remove( 'nocursor' );
1237
+ that.splitBar.classList.remove( 'nocursor' );
1221
1238
  }
1222
1239
 
1223
1240
  return this.sections;
@@ -1649,8 +1666,8 @@ class Area {
1649
1666
  _disableSplitResize() {
1650
1667
 
1651
1668
  this.resize = false;
1652
- this.split_bar.remove();
1653
- delete this.split_bar;
1669
+ this.splitBar.remove();
1670
+ delete this.splitBar;
1654
1671
  }
1655
1672
 
1656
1673
  _update() {
@@ -2471,6 +2488,18 @@ class SideBar {
2471
2488
  desc.innerHTML = key;
2472
2489
  entry.appendChild( desc );
2473
2490
 
2491
+ button.addEventListener("mouseenter", () => {
2492
+ setTimeout( () => {
2493
+ desc.style.display = "unset";
2494
+ }, 100 );
2495
+ });
2496
+
2497
+ button.addEventListener("mouseleave", () => {
2498
+ setTimeout( () => {
2499
+ desc.style.display = "none";
2500
+ }, 100 );
2501
+ });
2502
+
2474
2503
  entry.addEventListener("click", () => {
2475
2504
 
2476
2505
  const f = options.callback;
@@ -4092,14 +4121,17 @@ class Panel {
4092
4121
  * disabled: Make the widget disabled [false]
4093
4122
  * icon: Icon class to show as button value
4094
4123
  * img: Path to image to show as button value
4124
+ * title: Text to show in native Element title
4095
4125
  */
4096
4126
 
4097
4127
  addButton( name, value, callback, options = {} ) {
4098
4128
 
4099
- let widget = this.create_widget(name, Widget.BUTTON, options);
4129
+ let widget = this.create_widget( name, Widget.BUTTON, options );
4130
+
4100
4131
  widget.onGetValue = () => {
4101
4132
  return wValue.innerText;
4102
4133
  };
4134
+
4103
4135
  widget.onSetValue = ( newValue, skipCallback ) => {
4104
4136
  wValue.innerHTML =
4105
4137
  (options.icon ? "<a class='" + options.icon + "'></a>" :
@@ -4108,36 +4140,50 @@ class Panel {
4108
4140
 
4109
4141
  let element = widget.domEl;
4110
4142
 
4111
- var wValue = document.createElement('button');
4112
- if(options.icon || options.img)
4113
- wValue.title = value;
4143
+ var wValue = document.createElement( 'button' );
4144
+ wValue.title = options.title ?? "";
4114
4145
  wValue.className = "lexbutton";
4115
- if(options.selected)
4116
- wValue.classList.add("selected");
4117
- if(options.buttonClass)
4118
- wValue.classList.add(options.buttonClass);
4146
+
4147
+ if( options.selected )
4148
+ {
4149
+ wValue.classList.add( "selected" );
4150
+ }
4151
+
4152
+ if( options.buttonClass )
4153
+ {
4154
+ wValue.classList.add( options.buttonClass );
4155
+ }
4156
+
4119
4157
  wValue.innerHTML =
4120
4158
  (options.icon ? "<a class='" + options.icon + "'></a>" :
4121
4159
  ( options.img ? "<img src='" + options.img + "'>" : "<span>" + (value || "") + "</span>" ));
4122
4160
 
4123
4161
  wValue.style.width = "calc( 100% - " + (options.nameWidth ?? LX.DEFAULT_NAME_WIDTH) + ")";
4124
4162
 
4125
- if(options.disabled)
4126
- wValue.setAttribute("disabled", true);
4163
+ if( options.disabled )
4164
+ {
4165
+ wValue.setAttribute( "disabled", true );
4166
+ }
4127
4167
 
4128
4168
  wValue.addEventListener("click", e => {
4129
- if( options.selectable ) {
4169
+ if( options.selectable )
4170
+ {
4130
4171
  if( options.parent )
4172
+ {
4131
4173
  options.parent.querySelectorAll(".lexbutton.selected").forEach( e => { if(e == wValue) return; e.classList.remove("selected") } );
4174
+ }
4175
+
4132
4176
  wValue.classList.toggle('selected');
4133
4177
  }
4134
- this._trigger( new IEvent(name, value, e), callback );
4178
+
4179
+ this._trigger( new IEvent( name, value, e ), callback );
4135
4180
  });
4136
4181
 
4137
- element.appendChild(wValue);
4182
+ element.appendChild( wValue );
4138
4183
 
4139
4184
  // Remove branch padding and margins
4140
- if(!widget.name) {
4185
+ if( !widget.name )
4186
+ {
4141
4187
  wValue.className += " noname";
4142
4188
  wValue.style.width = "100%";
4143
4189
  }
@@ -6078,7 +6124,8 @@ class Panel {
6078
6124
 
6079
6125
  addProgress( name, value, options = {} ) {
6080
6126
 
6081
- if(!name) {
6127
+ if( !name )
6128
+ {
6082
6129
  throw("Set Widget Name!");
6083
6130
  }
6084
6131
 
@@ -6109,46 +6156,74 @@ class Panel {
6109
6156
  progress.max = options.max ?? 1;
6110
6157
  progress.value = value;
6111
6158
 
6112
- if(options.low)
6159
+ if( options.low )
6113
6160
  progress.low = options.low;
6114
- if(options.high)
6161
+ if( options.high )
6115
6162
  progress.high = options.high;
6116
- if(options.optimum)
6163
+ if( options.optimum )
6117
6164
  progress.optimum = options.optimum;
6118
6165
 
6119
- container.appendChild(progress);
6120
- element.appendChild(container);
6166
+ container.appendChild( progress );
6167
+ element.appendChild( container );
6121
6168
 
6122
- if(options.showValue) {
6123
- if(document.getElementById('progressvalue-' + name ))
6169
+ if( options.showValue )
6170
+ {
6171
+ if( document.getElementById('progressvalue-' + name ) )
6172
+ {
6124
6173
  document.getElementById('progressvalue-' + name ).remove();
6174
+ }
6175
+
6125
6176
  let span = document.createElement("span");
6126
6177
  span.id = "progressvalue-" + name;
6127
6178
  span.style.padding = "0px 5px";
6128
6179
  span.innerText = value;
6129
- container.appendChild(span);
6180
+ container.appendChild( span );
6130
6181
  }
6131
6182
 
6132
- if(options.editable) {
6133
- progress.classList.add("editable");
6134
- progress.addEventListener("mousemove", inner_mousemove.bind(this, value));
6135
- progress.addEventListener("mouseup", inner_mouseup.bind(this, progress));
6183
+ if( options.editable )
6184
+ {
6185
+ progress.classList.add( "editable" );
6186
+ progress.addEventListener( "mousedown", inner_mousedown );
6136
6187
 
6137
- function inner_mousemove(value, e) {
6138
-
6139
- if(e.which < 1)
6140
- return;
6141
- let v = this.getValue(name, value);
6142
- v+=e.movementX/100;
6143
- v = v.toFixed(2);
6144
- this.setValue(name, v);
6188
+ var that = this;
6145
6189
 
6146
- if(options.callback)
6147
- options.callback(v, e);
6190
+ function inner_mousedown( e )
6191
+ {
6192
+ var doc = that.root.ownerDocument;
6193
+ doc.addEventListener( 'mousemove', inner_mousemove );
6194
+ doc.addEventListener( 'mouseup', inner_mouseup );
6195
+ document.body.classList.add( 'noevents' );
6196
+ e.stopImmediatePropagation();
6197
+ e.stopPropagation();
6148
6198
  }
6149
6199
 
6150
- function inner_mouseup(el) {
6151
- el.removeEventListener("mousemove", inner_mousemove);
6200
+ function inner_mousemove( e )
6201
+ {
6202
+ let dt = -e.movementX;
6203
+
6204
+ if ( dt != 0 )
6205
+ {
6206
+ let v = that.getValue( name, value );
6207
+ v += e.movementX / 100;
6208
+ v = round( v );
6209
+ that.setValue( name, v );
6210
+
6211
+ if( options.callback )
6212
+ {
6213
+ options.callback( v, e );
6214
+ }
6215
+ }
6216
+
6217
+ e.stopPropagation();
6218
+ e.preventDefault();
6219
+ }
6220
+
6221
+ function inner_mouseup( e )
6222
+ {
6223
+ var doc = that.root.ownerDocument;
6224
+ doc.removeEventListener( 'mousemove', inner_mousemove );
6225
+ doc.removeEventListener( 'mouseup', inner_mouseup );
6226
+ document.body.classList.remove( 'noevents' );
6152
6227
  }
6153
6228
  }
6154
6229
 
@@ -7640,9 +7715,11 @@ class AssetView {
7640
7715
 
7641
7716
  this.skipBrowser = options.skipBrowser ?? false;
7642
7717
  this.skipPreview = options.skipPreview ?? false;
7718
+ this.useNativeTitle = options.useNativeTitle ?? false;
7643
7719
  this.onlyFolders = options.onlyFolders ?? true;
7644
7720
  this.previewActions = options.previewActions ?? [];
7645
7721
  this.contextMenu = options.contextMenu ?? [];
7722
+ this.onRefreshContent = options.onRefreshContent;
7646
7723
 
7647
7724
  if( !this.skipBrowser )
7648
7725
  {
@@ -7712,14 +7789,17 @@ class AssetView {
7712
7789
  * @method clear
7713
7790
  */
7714
7791
  clear() {
7792
+
7715
7793
  if( this.previewPanel )
7716
7794
  {
7717
7795
  this.previewPanel.clear();
7718
7796
  }
7797
+
7719
7798
  if( this.leftPanel )
7720
7799
  {
7721
7800
  this.leftPanel.clear();
7722
7801
  }
7802
+
7723
7803
  if( this.rightPanel )
7724
7804
  {
7725
7805
  this.rightPanel.clear()
@@ -7790,7 +7870,7 @@ class AssetView {
7790
7870
  children: this.data
7791
7871
  }
7792
7872
 
7793
- this.tree = this.leftPanel.addTree("Content Browser", tree_data, {
7873
+ this.tree = this.leftPanel.addTree( "Content Browser", tree_data, {
7794
7874
  // icons: tree_icons,
7795
7875
  filter: false,
7796
7876
  onlyFolders: this.onlyFolders,
@@ -7851,7 +7931,7 @@ class AssetView {
7851
7931
  this.rightPanel = area.addPanel({ className: 'lexassetcontentpanel' });
7852
7932
  }
7853
7933
 
7854
- const on_sort = (value, event) => {
7934
+ const on_sort = ( value, event ) => {
7855
7935
  const cmenu = addContextMenu( "Sort by", event, c => {
7856
7936
  c.add("Name", () => this._sortData('id') );
7857
7937
  c.add("Type", () => this._sortData('type') );
@@ -7861,10 +7941,12 @@ class AssetView {
7861
7941
  } );
7862
7942
  const parent = this.parent.root.parentElement;
7863
7943
  if( parent.classList.contains('lexdialog') )
7944
+ {
7864
7945
  cmenu.root.style.zIndex = (+getComputedStyle( parent ).zIndex) + 1;
7946
+ }
7865
7947
  }
7866
7948
 
7867
- const on_change_view = (value, event) => {
7949
+ const on_change_view = ( value, event ) => {
7868
7950
  const cmenu = addContextMenu( "Layout", event, c => {
7869
7951
  c.add("Content", () => this._setContentLayout( AssetView.LAYOUT_CONTENT ) );
7870
7952
  c.add("");
@@ -7875,7 +7957,7 @@ class AssetView {
7875
7957
  cmenu.root.style.zIndex = (+getComputedStyle( parent ).zIndex) + 1;
7876
7958
  }
7877
7959
 
7878
- const on_change_page = (value, event) => {
7960
+ const on_change_page = ( value, event ) => {
7879
7961
  if( !this.allowNextPage )
7880
7962
  {
7881
7963
  return;
@@ -7892,13 +7974,13 @@ class AssetView {
7892
7974
  }
7893
7975
 
7894
7976
  this.rightPanel.sameLine();
7895
- this.rightPanel.addDropdown("Filter", this.allowedTypes, this.allowedTypes[0], (v) => this._refreshContent.call(this, null, v), { width: "20%", minWidth: "128px" });
7896
- this.rightPanel.addText(null, this.searchValue ?? "", (v) => this._refreshContent.call(this, v, null), { placeholder: "Search assets.." });
7897
- this.rightPanel.addButton(null, "<a class='fa fa-arrow-up-short-wide'></a>", on_sort.bind(this), { className: "micro", title: "Sort" });
7898
- this.rightPanel.addButton(null, "<a class='fa-solid fa-grip'></a>", on_change_view.bind(this), { className: "micro", title: "View" });
7977
+ this.rightPanel.addDropdown( "Filter", this.allowedTypes, this.allowedTypes[ 0 ], v => this._refreshContent.call(this, null, v), { width: "20%", minWidth: "128px" } );
7978
+ this.rightPanel.addText( null, this.searchValue ?? "", v => this._refreshContent.call(this, v, null), { placeholder: "Search assets.." } );
7979
+ this.rightPanel.addButton( null, "<a class='fa fa-arrow-up-short-wide'></a>", on_sort.bind(this), { className: "micro", title: "Sort" } );
7980
+ this.rightPanel.addButton( null, "<a class='fa-solid fa-grip'></a>", on_change_view.bind(this), { className: "micro", title: "View" } );
7899
7981
  // Content Pages
7900
- this.rightPanel.addButton(null, "<a class='fa-solid fa-angles-left'></a>", on_change_page.bind(this, -1), { className: "micro", title: "Previous Page" });
7901
- this.rightPanel.addButton(null, "<a class='fa-solid fa-angles-right'></a>", on_change_page.bind(this, 1), { className: "micro", title: "Next Page" });
7982
+ this.rightPanel.addButton( null, "<a class='fa-solid fa-angles-left'></a>", on_change_page.bind(this, -1), { className: "micro", title: "Previous Page" } );
7983
+ this.rightPanel.addButton( null, "<a class='fa-solid fa-angles-right'></a>", on_change_page.bind(this, 1), { className: "micro", title: "Next Page" } );
7902
7984
  this.rightPanel.endLine();
7903
7985
 
7904
7986
  if( !this.skipBrowser )
@@ -7908,7 +7990,7 @@ class AssetView {
7908
7990
  {
7909
7991
  value: "Left",
7910
7992
  icon: "fa-solid fa-left-long",
7911
- callback: (domEl) => {
7993
+ callback: domEl => {
7912
7994
  if(!this.prevData.length) return;
7913
7995
  this.nextData.push( this.currentData );
7914
7996
  this.currentData = this.prevData.pop();
@@ -7919,7 +8001,7 @@ class AssetView {
7919
8001
  {
7920
8002
  value: "Right",
7921
8003
  icon: "fa-solid fa-right-long",
7922
- callback: (domEl) => {
8004
+ callback: domEl => {
7923
8005
  if(!this.nextData.length) return;
7924
8006
  this.prevData.push( this.currentData );
7925
8007
  this.currentData = this.nextData.pop();
@@ -7930,7 +8012,7 @@ class AssetView {
7930
8012
  {
7931
8013
  value: "Refresh",
7932
8014
  icon: "fa-solid fa-arrows-rotate",
7933
- callback: (domEl) => { this._refreshContent(); }
8015
+ callback: domEl => { this._refreshContent(); }
7934
8016
  }
7935
8017
  ], { width: "auto", noSelection: true } );
7936
8018
  this.rightPanel.addText(null, this.path.join('/'), null, { disabled: true, signal: "@on_folder_change", style: { fontWeight: "bolder", fontSize: "16px", color: "#aaa" } });
@@ -7942,17 +8024,17 @@ class AssetView {
7942
8024
  this.content.className = "lexassetscontent";
7943
8025
  this.rightPanel.root.appendChild(this.content);
7944
8026
 
7945
- this.content.addEventListener('dragenter', function(e) {
8027
+ this.content.addEventListener('dragenter', function( e ) {
7946
8028
  e.preventDefault();
7947
8029
  this.classList.add('dragging');
7948
8030
  });
7949
- this.content.addEventListener('dragleave', function(e) {
8031
+ this.content.addEventListener('dragleave', function( e ) {
7950
8032
  e.preventDefault();
7951
8033
  this.classList.remove('dragging');
7952
8034
  });
7953
- this.content.addEventListener('drop', (e) => {
8035
+ this.content.addEventListener('drop', ( e ) => {
7954
8036
  e.preventDefault();
7955
- this._processDrop(e);
8037
+ this._processDrop( e );
7956
8038
  });
7957
8039
  this.content.addEventListener('click', function() {
7958
8040
  this.querySelectorAll('.lexassetitem').forEach( i => i.classList.remove('selected') );
@@ -7963,9 +8045,9 @@ class AssetView {
7963
8045
 
7964
8046
  _refreshContent( searchValue, filter ) {
7965
8047
 
7966
- const isContentLayout = (this.layout == AssetView.LAYOUT_CONTENT); // default
8048
+ const isContentLayout = ( this.layout == AssetView.LAYOUT_CONTENT ); // default
7967
8049
 
7968
- this.filter = filter ?? (this.filter ?? "None");
8050
+ this.filter = filter ?? ( this.filter ?? "None" );
7969
8051
  this.searchValue = searchValue ?? (this.searchValue ?? "");
7970
8052
  this.content.innerHTML = "";
7971
8053
  this.content.className = (isContentLayout ? "lexassetscontent" : "lexassetscontent list");
@@ -7979,11 +8061,62 @@ class AssetView {
7979
8061
 
7980
8062
  let itemEl = document.createElement('li');
7981
8063
  itemEl.className = "lexassetitem " + item.type.toLowerCase();
7982
- itemEl.title = type + ": " + item.id;
7983
8064
  itemEl.tabIndex = -1;
7984
8065
  that.content.appendChild( itemEl );
7985
8066
 
7986
- if(item.selected != undefined) {
8067
+ if( !that.useNativeTitle )
8068
+ {
8069
+ let desc = document.createElement( 'span' );
8070
+ desc.className = 'lexitemdesc';
8071
+ desc.innerHTML = "File: " + item.id + "<br>Type: " + type;
8072
+ that.content.appendChild( desc );
8073
+
8074
+ itemEl.addEventListener("mousemove", e => {
8075
+
8076
+ if( !isContentLayout )
8077
+ {
8078
+ return;
8079
+ }
8080
+
8081
+ const rect = itemEl.getBoundingClientRect();
8082
+ const targetRect = e.target.getBoundingClientRect();
8083
+ const parentRect = desc.parentElement.getBoundingClientRect();
8084
+
8085
+ let localOffsetX = targetRect.x - parentRect.x - ( targetRect.x - rect.x );
8086
+ let localOffsetY = targetRect.y - parentRect.y - ( targetRect.y - rect.y );
8087
+
8088
+ if( e.target.classList.contains( "lexassettitle" ) )
8089
+ {
8090
+ localOffsetY += ( targetRect.y - rect.y );
8091
+ }
8092
+
8093
+ desc.style.left = (localOffsetX + e.offsetX + 12) + "px";
8094
+ desc.style.top = (localOffsetY + e.offsetY) + "px";
8095
+ });
8096
+
8097
+ itemEl.addEventListener("mouseenter", () => {
8098
+ if( isContentLayout )
8099
+ {
8100
+ desc.style.display = "unset";
8101
+ }
8102
+ });
8103
+
8104
+ itemEl.addEventListener("mouseleave", () => {
8105
+ if( isContentLayout )
8106
+ {
8107
+ setTimeout( () => {
8108
+ desc.style.display = "none";
8109
+ }, 100 );
8110
+ }
8111
+ });
8112
+ }
8113
+ else
8114
+ {
8115
+ itemEl.title = type + ": " + item.id;
8116
+ }
8117
+
8118
+ if( item.selected != undefined )
8119
+ {
7987
8120
  let span = document.createElement('span');
7988
8121
  span.className = "lexcheckbox";
7989
8122
  let checkbox_input = document.createElement('input');
@@ -8005,6 +8138,7 @@ class AssetView {
8005
8138
  itemEl.appendChild(span);
8006
8139
 
8007
8140
  }
8141
+
8008
8142
  let title = document.createElement('span');
8009
8143
  title.className = "lexassettitle";
8010
8144
  title.innerText = item.id;
@@ -8097,14 +8231,20 @@ class AssetView {
8097
8231
 
8098
8232
  LX.addContextMenu( multiple > 1 ? (multiple + " selected") :
8099
8233
  isFolder ? item.id : item.type, e, m => {
8100
- if(multiple <= 1)
8234
+ if( multiple <= 1 )
8235
+ {
8101
8236
  m.add("Rename");
8237
+ }
8102
8238
  if( !isFolder )
8103
- m.add("Clone", that._clone_item.bind(that, item));
8104
- if(multiple <= 1)
8239
+ {
8240
+ m.add("Clone", that._cloneItem.bind( that, item ));
8241
+ }
8242
+ if( multiple <= 1 )
8243
+ {
8105
8244
  m.add("Properties");
8245
+ }
8106
8246
  m.add("");
8107
- m.add("Delete", that._delete_item.bind(that, item));
8247
+ m.add("Delete", that._deleteItem.bind( that, item ));
8108
8248
  });
8109
8249
  });
8110
8250
  }
@@ -8153,8 +8293,14 @@ class AssetView {
8153
8293
  item.domEl = add_item( item );
8154
8294
  }
8155
8295
  }
8296
+
8156
8297
  this.allowNextPage = filteredData.length - 1 > AssetView.MAX_PAGE_ELEMENTS;
8157
8298
  LX.emit("@on_page_change", "Page " + this.contentPage + " / " + ((((filteredData.length - 1) / AssetView.MAX_PAGE_ELEMENTS )|0) + 1));
8299
+
8300
+ if( this.onRefreshContent )
8301
+ {
8302
+ this.onRefreshContent( searchValue, filter );
8303
+ }
8158
8304
  }
8159
8305
 
8160
8306
  /**
@@ -8318,21 +8464,26 @@ class AssetView {
8318
8464
 
8319
8465
  _cloneItem( item ) {
8320
8466
 
8321
- const idx = this.currentData.indexOf(item);
8322
- if(idx > -1) {
8323
- delete item.domEl;
8324
- delete item.folder;
8325
- const new_item = deepCopy( item );
8326
- this.currentData.splice(idx, 0, new_item);
8327
- this._refreshContent(this.searchValue, this.filter);
8467
+ const idx = this.currentData.indexOf( item );
8468
+ if( idx < 0 )
8469
+ {
8470
+ return;
8471
+ }
8472
+
8473
+ delete item.domEl;
8474
+ delete item.folder;
8475
+ const new_item = deepCopy( item );
8476
+ this.currentData.splice( idx, 0, new_item );
8328
8477
 
8329
- if(this.onevent) {
8330
- const event = new AssetViewEvent(AssetViewEvent.ASSET_CLONED, item );
8331
- this.onevent( event );
8332
- }
8478
+ this._refreshContent( this.searchValue, this.filter );
8333
8479
 
8334
- this._processData(this.data);
8480
+ if( this.onevent )
8481
+ {
8482
+ const event = new AssetViewEvent( AssetViewEvent.ASSET_CLONED, item );
8483
+ this.onevent( event );
8335
8484
  }
8485
+
8486
+ this._processData( this.data );
8336
8487
  }
8337
8488
  }
8338
8489
 
@@ -8350,7 +8501,7 @@ Object.assign(LX, {
8350
8501
  * @param {Object} request object with all the parameters like data (for sending forms), dataType, success, error
8351
8502
  * @param {Function} on_complete
8352
8503
  **/
8353
- request(request) {
8504
+ request( request ) {
8354
8505
 
8355
8506
  var dataType = request.dataType || "text";
8356
8507
  if(dataType == "json") //parse it locally