lexgui 0.6.11 → 0.6.12

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.
@@ -2859,18 +2859,18 @@ class CodeEditor {
2859
2859
  }
2860
2860
 
2861
2861
  const lang = this.languages[ this.highlight ];
2862
- const local_line_num = this.toLocalLine( linenum );
2863
- const gutter_line = "<span class='line-gutter'>" + (linenum + 1) + "</span>";
2862
+ const localLineNum = this.toLocalLine( linenum );
2863
+ const gutterLineHtml = "<span class='line-gutter'>" + (linenum + 1) + "</span>";
2864
2864
 
2865
2865
  const UPDATE_LINE = ( html ) => {
2866
2866
  if( !force ) // Single line update
2867
2867
  {
2868
- this.code.childNodes[ local_line_num ].innerHTML = gutter_line + html;
2868
+ this.code.childNodes[ localLineNum ].innerHTML = gutterLineHtml + html;
2869
2869
  this._setActiveLine( linenum );
2870
2870
  this._clearTmpVariables();
2871
2871
  }
2872
2872
  else // Update all lines at once
2873
- return "<pre>" + ( gutter_line + html ) + "</pre>";
2873
+ return "<pre>" + ( gutterLineHtml + html ) + "</pre>";
2874
2874
  }
2875
2875
 
2876
2876
  // multi-line strings not supported by now
@@ -2883,14 +2883,15 @@ class CodeEditor {
2883
2883
  // Single line
2884
2884
  if( !force )
2885
2885
  {
2886
- LX.deleteElement( this.code.childNodes[ local_line_num ] );
2887
- this.code.insertChildAtIndex( document.createElement( 'pre' ), local_line_num );
2886
+ LX.deleteElement( this.code.childNodes[ localLineNum ] );
2887
+ this.code.insertChildAtIndex( document.createElement( 'pre' ), localLineNum );
2888
2888
  }
2889
2889
 
2890
2890
  // Early out check for no highlighting languages
2891
2891
  if( this.highlight == 'Plain Text' )
2892
2892
  {
2893
- return UPDATE_LINE( linestring );
2893
+ const plainTextHtml = linestring.replaceAll('<', '&lt;').replaceAll('>', '&gt;');
2894
+ return UPDATE_LINE( plainTextHtml );
2894
2895
  }
2895
2896
 
2896
2897
  this._currentLineNumber = linenum;
@@ -2899,9 +2900,11 @@ class CodeEditor {
2899
2900
  const tokensToEvaluate = this._getTokensFromLine( linestring );
2900
2901
 
2901
2902
  if( !tokensToEvaluate.length )
2902
- return "<pre><span class='line-gutter'>" + linenum + "</span></pre>";
2903
+ {
2904
+ return "<pre><span class='line-gutter'>" + linenum + "</span></pre>";
2905
+ }
2903
2906
 
2904
- var line_inner_html = "";
2907
+ var lineInnerHtml = "";
2905
2908
 
2906
2909
  // Process all tokens
2907
2910
  for( var i = 0; i < tokensToEvaluate.length; ++i )
@@ -2929,7 +2932,7 @@ class CodeEditor {
2929
2932
  this._buildingBlockComment = linenum;
2930
2933
  }
2931
2934
 
2932
- line_inner_html += this._evaluateToken( {
2935
+ lineInnerHtml += this._evaluateToken( {
2933
2936
  token: token,
2934
2937
  prev: prev,
2935
2938
  prevWithSpaces: tokensToEvaluate[ i - 1 ],
@@ -2942,7 +2945,7 @@ class CodeEditor {
2942
2945
  } );
2943
2946
  }
2944
2947
 
2945
- return UPDATE_LINE( line_inner_html );
2948
+ return UPDATE_LINE( lineInnerHtml );
2946
2949
  }
2947
2950
 
2948
2951
  _lineHasComment( linestring ) {
@@ -196,6 +196,7 @@ class Timeline {
196
196
  signal: "@on_set_time_" + this.uniqueID,
197
197
  step: 0.01, min: 0, precision: 3,
198
198
  skipSlider: true,
199
+ skipReset: true,
199
200
  nameWidth: "auto"
200
201
  });
201
202
 
@@ -205,6 +206,7 @@ class Timeline {
205
206
  units: "s",
206
207
  step: 0.01, min: 0,
207
208
  signal: "@on_set_duration_" + this.uniqueID,
209
+ skipReset: true,
208
210
  nameWidth: "auto"
209
211
  });
210
212
 
@@ -400,13 +402,9 @@ class Timeline {
400
402
  */
401
403
  setAnimationClip( animation, needsToProcess = true ) {
402
404
 
403
- if ( this.unSelectAllKeyFrames ){
404
- this.unSelectAllKeyFrames();
405
- }
406
- if ( this.unHoverAll ){
407
- this.unHoverAll();
408
- }
409
- this.unSelectAllTracks();
405
+ this.deselectAllElements();
406
+ this.deselectAllTracks();
407
+
410
408
  this.selectedItems = [];
411
409
 
412
410
  this.clearState();
@@ -832,11 +830,13 @@ class Timeline {
832
830
  this.movingKeys = false;
833
831
  this.timeBeforeMove = null;
834
832
  this.boxSelection = false; // after mouseup
835
- this.unSelectAllTracks();
833
+ this.deselectAllTracks();
836
834
  }
837
835
 
838
836
 
839
837
  if( e.type == "mousedown") {
838
+ window.getSelection().empty(); // if canvas DOM is selected, dragging does not work properly. Deselect it
839
+
840
840
  // e.preventDefault();
841
841
 
842
842
  this.clickTime = LX.getTime();
@@ -1079,7 +1079,7 @@ class Timeline {
1079
1079
  return;
1080
1080
  }
1081
1081
 
1082
- this.unSelectAllTracks();
1082
+ this.deselectAllTracks();
1083
1083
 
1084
1084
  let track = this.animationClip.tracks[ trackIdx ];
1085
1085
  track.isSelected = true;
@@ -1090,7 +1090,7 @@ class Timeline {
1090
1090
  }
1091
1091
 
1092
1092
  // Only affects render visualisation
1093
- unSelectAllTracks() {
1093
+ deselectAllTracks() {
1094
1094
 
1095
1095
  if( !this.animationClip ){
1096
1096
  return;
@@ -1102,7 +1102,7 @@ class Timeline {
1102
1102
  }
1103
1103
  }
1104
1104
 
1105
- unselectAllElements(){
1105
+ deselectAllElements(){
1106
1106
 
1107
1107
  }
1108
1108
 
@@ -1149,7 +1149,7 @@ class Timeline {
1149
1149
 
1150
1150
  if (!toBeShown.length){ return false; }
1151
1151
 
1152
- this.unselectAllElements();
1152
+ this.deselectAllElements();
1153
1153
 
1154
1154
  const combinedState = toBeShown.pop();
1155
1155
  const combinedStateToStore = [];
@@ -1555,8 +1555,8 @@ class KeyFramesTimeline extends Timeline {
1555
1555
  }
1556
1556
 
1557
1557
  // OVERRIDE
1558
- unselectAllElements(){
1559
- this.unSelectAllKeyFrames();
1558
+ deselectAllElements(){
1559
+ this.deselectAllKeyFrames();
1560
1560
  this.unHoverAll();
1561
1561
  }
1562
1562
 
@@ -1568,7 +1568,7 @@ class KeyFramesTimeline extends Timeline {
1568
1568
  changeSelectedItems( itemsToAdd = null, itemsToRemove = null, skipCallback = false ) {
1569
1569
 
1570
1570
  // TODO: maybe make this un-functions more general
1571
- this.unSelectAllKeyFrames();
1571
+ this.deselectAllKeyFrames();
1572
1572
  this.unHoverAll();
1573
1573
 
1574
1574
  const tracks = this.animationClip.tracks;
@@ -1717,7 +1717,7 @@ class KeyFramesTimeline extends Timeline {
1717
1717
  const keyFrameIdx = this.getCurrentKeyFrame( track, this.xToTime( localX ), this.secondsPerPixel * 5 );
1718
1718
  if ( keyFrameIdx > -1 ){
1719
1719
  track.selected[keyFrameIdx] ?
1720
- this.unSelectKeyFrame(track.trackIdx, keyFrameIdx) :
1720
+ this.deselectKeyFrame(track.trackIdx, keyFrameIdx) :
1721
1721
  this.processSelectionKeyFrame( track.trackIdx, keyFrameIdx, true );
1722
1722
  }
1723
1723
  }
@@ -1742,10 +1742,10 @@ class KeyFramesTimeline extends Timeline {
1742
1742
  else if( !this.movingKeys && !discard ){ // if not moving timeline and not adding keyframes through e.shiftkey (just a click)
1743
1743
 
1744
1744
  if ( this.lastKeyFramesSelected.length ){
1745
- if (this.onUnselectKeyFrames){
1746
- this.onUnselectKeyFrames( this.lastKeyFramesSelected );
1745
+ if (this.onDeselectKeyFrames){
1746
+ this.onDeselectKeyFrames( this.lastKeyFramesSelected );
1747
1747
  }
1748
- this.unSelectAllKeyFrames();
1748
+ this.deselectAllKeyFrames();
1749
1749
  }
1750
1750
  if (track){
1751
1751
  const keyFrameIndex = this.getCurrentKeyFrame( track, this.xToTime( localX ), this.secondsPerPixel * 5 );
@@ -2129,27 +2129,43 @@ class KeyFramesTimeline extends Timeline {
2129
2129
  //draw lines
2130
2130
  ctx.strokeStyle = "white";
2131
2131
  ctx.beginPath();
2132
- for(let j = 0; j < keyframes.length; ++j){
2133
2132
 
2134
- let time = keyframes[j];
2135
- let keyframePosX = this.timeToX( time );
2136
- let value = values[j];
2137
- value = ((value - valueRange[0]) / (valueRange[1] - valueRange[0])) * (-displayRange) + (trackHeight - defaultPointSize); // normalize and offset
2133
+ if ( keyframes.length > 1){
2134
+ let startPosX = this.timeToX( keyframes[0] );
2135
+ let startValue = values[0];
2136
+ startValue = ((startValue - valueRange[0]) / (valueRange[1] - valueRange[0])) * (-displayRange) + (trackHeight - defaultPointSize); // normalize and offset
2137
+ ctx.moveTo( startPosX, startValue );
2138
2138
 
2139
- if( time < startTime ){
2140
- ctx.moveTo( keyframePosX, value );
2141
- continue;
2142
- }
2139
+ for(let j = 1; j < keyframes.length; ++j){
2143
2140
 
2144
- //convert to timeline track range
2145
- ctx.lineTo( keyframePosX, value );
2146
-
2147
- if ( time > endTime ){
2148
- break; //end loop, but print line
2141
+ let time = keyframes[j];
2142
+ let keyframePosX = this.timeToX( time );
2143
+ let value = values[j];
2144
+ value = ((value - valueRange[0]) / (valueRange[1] - valueRange[0])) * (-displayRange) + (trackHeight - defaultPointSize); // normalize and offset
2145
+
2146
+ if( time < startTime ){
2147
+ ctx.moveTo( keyframePosX, value );
2148
+ continue;
2149
+ }
2150
+
2151
+ if ( time > endTime ){
2152
+ let lastKeyframePosX = this.timeToX( keyframes[j-1] );
2153
+ let dt = keyframePosX - lastKeyframePosX;
2154
+ if ( dt > 0 ){
2155
+ let lastValue = values[j-1];
2156
+ lastValue = ((lastValue - valueRange[0]) / (valueRange[1] - valueRange[0])) * (-displayRange) + (trackHeight - defaultPointSize); // normalize and offset
2157
+ let f = (this.timeToX( endTime ) - lastKeyframePosX) / dt;
2158
+ ctx.lineTo( lastKeyframePosX + dt * f, lastValue * (1-f) + value * f );
2159
+ }
2160
+ break; //end loop, but print line
2161
+ }
2162
+
2163
+ //convert to timeline track range
2164
+ ctx.lineTo( keyframePosX, value );
2149
2165
  }
2166
+ ctx.stroke();
2150
2167
  }
2151
- ctx.stroke();
2152
-
2168
+
2153
2169
  //draw points
2154
2170
  ctx.fillStyle = Timeline.KEYFRAME_COLOR;
2155
2171
  for(let j = 0; j < keyframes.length; ++j)
@@ -2604,7 +2620,7 @@ class KeyFramesTimeline extends Timeline {
2604
2620
  if ( !this.clipboard.keyframes ){ return false; }
2605
2621
 
2606
2622
  this.unHoverAll();
2607
- this.unSelectAllKeyFrames();
2623
+ this.deselectAllKeyFrames();
2608
2624
 
2609
2625
  let clipboardTracks = this.clipboard.keyframes;
2610
2626
  let globalStart = Infinity;
@@ -2933,16 +2949,16 @@ class KeyFramesTimeline extends Timeline {
2933
2949
  return h;
2934
2950
  }
2935
2951
 
2936
- unSelectAllKeyFrames() {
2952
+ deselectAllKeyFrames() {
2937
2953
 
2938
2954
  for(let [trackIdx, keyIndex] of this.lastKeyFramesSelected) {
2939
2955
  this.animationClip.tracks[trackIdx].selected[keyIndex] = false;
2940
2956
  }
2941
2957
 
2942
- // Something has been unselected
2943
- const unselected = this.lastKeyFramesSelected.length > 0;
2958
+ // Something has been deselected
2959
+ const deselected = this.lastKeyFramesSelected.length > 0;
2944
2960
  this.lastKeyFramesSelected.length = 0;
2945
- return unselected;
2961
+ return deselected;
2946
2962
  }
2947
2963
 
2948
2964
  isKeyFrameSelected( track, index ) {
@@ -2981,7 +2997,7 @@ class KeyFramesTimeline extends Timeline {
2981
2997
  return selection;
2982
2998
  }
2983
2999
 
2984
- unSelectKeyFrame( trackIdx, frameIdx ){
3000
+ deselectKeyFrame( trackIdx, frameIdx ){
2985
3001
  const track = this.animationClip.tracks[trackIdx];
2986
3002
  if( track.locked || !track.active || !track.selected[frameIdx] )
2987
3003
  return false;
@@ -3017,7 +3033,7 @@ class KeyFramesTimeline extends Timeline {
3017
3033
  return;
3018
3034
 
3019
3035
  if(!multipleSelection) {
3020
- this.unSelectAllKeyFrames();
3036
+ this.deselectAllKeyFrames();
3021
3037
  }
3022
3038
 
3023
3039
  this.selectKeyFrame(trackIdx, keyFrameIndex);
@@ -3039,7 +3055,7 @@ class KeyFramesTimeline extends Timeline {
3039
3055
  }
3040
3056
 
3041
3057
  this.unHoverAll();
3042
- this.unSelectAllKeyFrames();
3058
+ this.deselectAllKeyFrames();
3043
3059
 
3044
3060
  this.saveState(track.trackIdx);
3045
3061
 
@@ -3139,9 +3155,30 @@ class ClipsTimeline extends Timeline {
3139
3155
  track.hovered = (new Array(numClips)).fill(false);
3140
3156
  }
3141
3157
 
3158
+ // sanity check. Also done in addClip
3159
+ for( let i = 0; i < track.clips.length; ++i ){
3160
+ track.clips[i].active = track.clips[i].active ?? true;
3161
+ }
3142
3162
  return track;
3143
3163
  }
3144
3164
 
3165
+ // provides an base example of a proper clip
3166
+ instantiateClip(options = {}){
3167
+ return {
3168
+ id: options.id ?? (options.name ?? "clip"),
3169
+
3170
+ start: options.start ?? 0,
3171
+ duration: options.duration ?? 1,
3172
+ fadein: options.fadein ?? undefined,
3173
+ fadeout: options.fadeout ?? undefined,
3174
+
3175
+ clipColor: options.clipColor ?? LX.getThemeColor("global-color-accent"),
3176
+ fadeColor: options.fadeColor ?? null,
3177
+ active: options.active ?? true,
3178
+ trackIdx: -1, // filled by addClip
3179
+ }
3180
+
3181
+ }
3145
3182
  // use default updateleftpanel
3146
3183
  // generateSelectedItemsTreeData(){}
3147
3184
 
@@ -3171,8 +3208,8 @@ class ClipsTimeline extends Timeline {
3171
3208
  }
3172
3209
 
3173
3210
  // OVERRIDE
3174
- unselectAllElements(){
3175
- this.unSelectAllClips();
3211
+ deselectAllElements(){
3212
+ this.deselectAllClips();
3176
3213
  this.unHoverAll();
3177
3214
  }
3178
3215
 
@@ -3183,7 +3220,7 @@ class ClipsTimeline extends Timeline {
3183
3220
  changeSelectedItems( ) {
3184
3221
 
3185
3222
  // TODO: maybe make this un-functions more general
3186
- this.unSelectAllClips();
3223
+ this.deselectAllClips();
3187
3224
  this.unHoverAll();
3188
3225
 
3189
3226
  this.selectedItems = this.animationClip.tracks.slice();
@@ -3214,7 +3251,7 @@ class ClipsTimeline extends Timeline {
3214
3251
  let clipIndex = this.getClipOnTime( track, this.xToTime( localX ), this.secondsPerPixel * 5 );
3215
3252
  if ( clipIndex > -1 ){
3216
3253
  track.selected[clipIndex] ?
3217
- this.unselectClip( track.trackIdx, clipIndex ) :
3254
+ this.deselectClip( track.trackIdx, clipIndex ) :
3218
3255
  this.selectClip( track.trackIdx, clipIndex, false );
3219
3256
  }
3220
3257
  }
@@ -3302,13 +3339,16 @@ class ClipsTimeline extends Timeline {
3302
3339
  this.movingKeys = true;
3303
3340
  }
3304
3341
  else if( !track || track && this.getClipOnTime(track, time, 0.001) == -1) { // clicked on empty space
3305
- this.unSelectAllClips();
3306
- if(this.onSelectClip)
3307
- this.onSelectClip(null);
3342
+ if ( this.lastClipsSelected.length ){
3343
+ this.deselectAllClips();
3344
+ if(this.onSelectClip){
3345
+ this.onSelectClip(null);
3346
+ }
3347
+ }
3308
3348
  }
3309
3349
  else if (track && (this.dragClipMode == "duration" || this.dragClipMode == "fadein" || this.dragClipMode == "fadeout" )) { // clicked while mouse was over fadeIn, fadeOut, duration
3310
3350
  const clipIdx = this.getClipOnTime(track, this.xToTime(localX), 0.001);
3311
- this.selectClip( track.trackIdx, clipIdx ); // select current clip if any (unselect others)
3351
+ this.selectClip( track.trackIdx, clipIdx ); // select current clip if any (deselect others)
3312
3352
  if ( this.lastClipsSelected.length ){
3313
3353
  this.saveState(track.trackIdx);
3314
3354
  }
@@ -3621,7 +3661,7 @@ class ClipsTimeline extends Timeline {
3621
3661
 
3622
3662
  if ( track ){
3623
3663
  const clipIdx = this.getClipOnTime(track, this.xToTime(localX), 0.001);
3624
- this.selectClip(track.trackIdx, clipIdx); // unselect and try to select clip in localX, if any
3664
+ this.selectClip(track.trackIdx, clipIdx); // deselect and try to select clip in localX, if any
3625
3665
  }
3626
3666
  }
3627
3667
 
@@ -3737,14 +3777,14 @@ class ClipsTimeline extends Timeline {
3737
3777
  // Overwrite clip color state depending on its state
3738
3778
  ctx.globalAlpha = 1;
3739
3779
  ctx.fillStyle = clip.clipColor || (track.hovered[j] ? Timeline.KEYFRAME_COLOR_HOVERED : (track.selected[j] ? Timeline.TRACK_SELECTED : Timeline.KEYFRAME_COLOR));
3740
- if(!this.active || !track.active) {
3780
+ if(!this.active || !track.active || !clip.active) {
3741
3781
  ctx.fillStyle = Timeline.KEYFRAME_COLOR_INACTIVE;
3742
3782
  }
3743
3783
 
3744
3784
  // Draw clip background
3745
3785
  ctx.roundRect( x, y + offset, w, trackHeight , 5, true);
3746
3786
 
3747
- if(this.active && track.active) {
3787
+ if(this.active && track.active && clip.active) {
3748
3788
 
3749
3789
  ctx.fillStyle = clip.fadeColor ?? "#0004";
3750
3790
 
@@ -3822,6 +3862,8 @@ class ClipsTimeline extends Timeline {
3822
3862
  addClip( clip, trackIdx = -1, offsetTime = 0, searchStartTrackIdx = 0 ) {
3823
3863
  if ( !this.animationClip ){ return -1; }
3824
3864
 
3865
+ this.deselectAllElements(); // TODO: consider adjusting values of hovered and selected instead of deselecting everything
3866
+
3825
3867
  // Update clip information
3826
3868
  let newStart = clip.start + offsetTime;
3827
3869
  if(clip.fadein != undefined)
@@ -3830,6 +3872,9 @@ class ClipsTimeline extends Timeline {
3830
3872
  clip.fadeout += (newStart - clip.start);
3831
3873
  clip.start = newStart;
3832
3874
 
3875
+ // sanity check
3876
+ clip.active = clip.active ?? true;
3877
+
3833
3878
  // find appropriate track
3834
3879
  if ( trackIdx >= this.animationClip.tracks.length ){ // new track ad the end
3835
3880
  trackIdx = this.addNewTrack();
@@ -3856,6 +3901,8 @@ class ClipsTimeline extends Timeline {
3856
3901
  // }
3857
3902
  }
3858
3903
 
3904
+ clip.trackIdx = trackIdx;
3905
+
3859
3906
  const track = this.animationClip.tracks[trackIdx];
3860
3907
 
3861
3908
  // Find new index
@@ -4097,7 +4144,7 @@ class ClipsTimeline extends Timeline {
4097
4144
  }
4098
4145
 
4099
4146
  pasteContent( time = this.currentTime ) {
4100
- this.unSelectAllClips();
4147
+ this.deselectAllClips();
4101
4148
 
4102
4149
  if(!this.clipboard)
4103
4150
  return;
@@ -4155,6 +4202,11 @@ class ClipsTimeline extends Timeline {
4155
4202
  const track = this.animationClip.tracks[trackIdx];
4156
4203
  const clips = this.cloneClips(track.clips, 0, ClipsTimeline.CLONEREASON_HISTORY);
4157
4204
 
4205
+ // sanity check in case cloneClips misses this
4206
+ for( let i = 0; i < clips.length; ++i ){
4207
+ clips[i].trackIdx = trackIdx;
4208
+ }
4209
+
4158
4210
  const undoStep = {
4159
4211
  trackIdx: trackIdx, // already done by saveState
4160
4212
  clips: clips,
@@ -4187,6 +4239,11 @@ class ClipsTimeline extends Timeline {
4187
4239
  track.selected.fill(false);
4188
4240
  track.hovered.fill(false);
4189
4241
 
4242
+ // sanity check. Also done in addClip
4243
+ for( let i = 0; i < track.clips.length; ++i ){
4244
+ track.clips[i].active = track.clips[i].active ?? true;
4245
+ }
4246
+
4190
4247
  return stateToReturn;
4191
4248
  }
4192
4249
 
@@ -4212,20 +4269,20 @@ class ClipsTimeline extends Timeline {
4212
4269
  return -1;
4213
4270
  };
4214
4271
 
4215
- unSelectAllClips() {
4272
+ deselectAllClips() {
4216
4273
 
4217
4274
  for(let [trackIdx, clipIdx] of this.lastClipsSelected) {
4218
4275
  this.animationClip.tracks[trackIdx].selected[clipIdx]= false;
4219
4276
  }
4220
- // Something has been unselected
4221
- const unselected = this.lastClipsSelected.length > 0;
4277
+ // Something has been deselected
4278
+ const deselected = this.lastClipsSelected.length > 0;
4222
4279
  this.lastClipsSelected.length = 0;
4223
- return unselected;
4280
+ return deselected;
4224
4281
  }
4225
4282
 
4226
4283
  selectAll( skipCallback = false) {
4227
4284
 
4228
- this.unSelectAllClips();
4285
+ this.deselectAllClips();
4229
4286
  for(let trackIdx = 0; trackIdx < this.animationClip.tracks.length; trackIdx++) {
4230
4287
  for(let clipIdx = 0; clipIdx < this.animationClip.tracks[trackIdx].clips.length; clipIdx++) {
4231
4288
  this.animationClip.tracks[trackIdx].selected[clipIdx] = true;
@@ -4236,10 +4293,10 @@ class ClipsTimeline extends Timeline {
4236
4293
  this.onSelectClip(null);
4237
4294
  }
4238
4295
 
4239
- selectClip( trackIdx, clipIndex, unselect = true, skipCallback = false ) {
4296
+ selectClip( trackIdx, clipIndex, deselect = true, skipCallback = false ) {
4240
4297
 
4241
- if(unselect){
4242
- this.unSelectAllClips();
4298
+ if(deselect){
4299
+ this.deselectAllClips();
4243
4300
  }
4244
4301
 
4245
4302
  if(clipIndex < 0){
@@ -4270,7 +4327,7 @@ class ClipsTimeline extends Timeline {
4270
4327
  return clipIndex;
4271
4328
  }
4272
4329
 
4273
- unselectClip( trackIdx, clipIndex ){
4330
+ deselectClip( trackIdx, clipIndex ){
4274
4331
 
4275
4332
  if(clipIndex == -1){
4276
4333
  return -1;
@@ -4283,7 +4340,7 @@ class ClipsTimeline extends Timeline {
4283
4340
 
4284
4341
  track.selected[clipIndex] = false;
4285
4342
 
4286
- // unselect
4343
+ // deselect
4287
4344
  for( let i = 0; i < this.lastClipsSelected.length; ++i){
4288
4345
  let t = this.lastClipsSelected[i];
4289
4346
  if ( t[0] == trackIdx && t[1] == clipIndex ){
@@ -4332,11 +4389,10 @@ class ClipsTimeline extends Timeline {
4332
4389
  validateDuration(t) {
4333
4390
  for(let i = 0; i < this.animationClip.tracks.length; i++) {
4334
4391
  const track = this.animationClip.tracks[i];
4335
- const clipsIdxs = this.getClipsInRange( track, t , this.animationClip.duration, 0 );
4336
- if(!clipsIdxs)
4337
- continue;
4338
- const clip = track.clips[clipsIdxs[clipsIdxs.length - 1]];
4339
- t = Math.max(t, clip.start + clip.duration);
4392
+ if ( track.clips.length ){
4393
+ const clip = track.clips[track.clips.length-1]; // assuming they are ordered ascendently
4394
+ t = Math.max(t, clip.start + clip.duration);
4395
+ }
4340
4396
  }
4341
4397
  return t;
4342
4398
  }
@@ -4344,7 +4400,7 @@ class ClipsTimeline extends Timeline {
4344
4400
  setDuration( t, skipCallback = false, updateHeader = true ){
4345
4401
  const oldT = t;
4346
4402
  const newT = this.validateDuration(t);
4347
- super.setDuration( this.validateDuration(t), skipCallback, oldT != newT || updateHeader );
4403
+ super.setDuration( newT, skipCallback, oldT != newT || updateHeader );
4348
4404
  }
4349
4405
  }
4350
4406
 
package/build/lexgui.css CHANGED
@@ -853,6 +853,12 @@ a svg, svg path {
853
853
  }
854
854
  }
855
855
 
856
+ @media (min-width: 2100px) {
857
+ .lexcontainer.wrapper {
858
+ max-width: 1736px;
859
+ }
860
+ }
861
+
856
862
  .lextooltip {
857
863
  position: fixed;
858
864
  background-color: var(--global-text-primary);