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.
- package/build/components/codeeditor.js +14 -11
- package/build/components/timeline.js +127 -71
- package/build/lexgui.css +6 -0
- package/build/lexgui.js +390 -60
- package/build/lexgui.min.css +1 -1
- package/build/lexgui.min.js +1 -1
- package/build/lexgui.module.js +414 -84
- package/build/lexgui.module.min.js +1 -1
- package/changelog.md +19 -1
- package/demo.js +9 -2
- package/examples/all_widgets.html +1 -0
- package/examples/timeline.html +1 -1
- package/package.json +1 -1
|
@@ -2859,18 +2859,18 @@ class CodeEditor {
|
|
|
2859
2859
|
}
|
|
2860
2860
|
|
|
2861
2861
|
const lang = this.languages[ this.highlight ];
|
|
2862
|
-
const
|
|
2863
|
-
const
|
|
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[
|
|
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>" + (
|
|
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[
|
|
2887
|
-
this.code.insertChildAtIndex( document.createElement( 'pre' ),
|
|
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
|
-
|
|
2893
|
+
const plainTextHtml = linestring.replaceAll('<', '<').replaceAll('>', '>');
|
|
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
|
-
|
|
2903
|
+
{
|
|
2904
|
+
return "<pre><span class='line-gutter'>" + linenum + "</span></pre>";
|
|
2905
|
+
}
|
|
2903
2906
|
|
|
2904
|
-
var
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
404
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
1559
|
-
this.
|
|
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.
|
|
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.
|
|
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.
|
|
1746
|
-
this.
|
|
1745
|
+
if (this.onDeselectKeyFrames){
|
|
1746
|
+
this.onDeselectKeyFrames( this.lastKeyFramesSelected );
|
|
1747
1747
|
}
|
|
1748
|
-
this.
|
|
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
|
-
|
|
2135
|
-
let
|
|
2136
|
-
let
|
|
2137
|
-
|
|
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
|
-
|
|
2140
|
-
ctx.moveTo( keyframePosX, value );
|
|
2141
|
-
continue;
|
|
2142
|
-
}
|
|
2139
|
+
for(let j = 1; j < keyframes.length; ++j){
|
|
2143
2140
|
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
|
2943
|
-
const
|
|
2958
|
+
// Something has been deselected
|
|
2959
|
+
const deselected = this.lastKeyFramesSelected.length > 0;
|
|
2944
2960
|
this.lastKeyFramesSelected.length = 0;
|
|
2945
|
-
return
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
3175
|
-
this.
|
|
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.
|
|
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.
|
|
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.
|
|
3306
|
-
|
|
3307
|
-
this.onSelectClip
|
|
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 (
|
|
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); //
|
|
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.
|
|
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
|
-
|
|
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
|
|
4221
|
-
const
|
|
4277
|
+
// Something has been deselected
|
|
4278
|
+
const deselected = this.lastClipsSelected.length > 0;
|
|
4222
4279
|
this.lastClipsSelected.length = 0;
|
|
4223
|
-
return
|
|
4280
|
+
return deselected;
|
|
4224
4281
|
}
|
|
4225
4282
|
|
|
4226
4283
|
selectAll( skipCallback = false) {
|
|
4227
4284
|
|
|
4228
|
-
this.
|
|
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,
|
|
4296
|
+
selectClip( trackIdx, clipIndex, deselect = true, skipCallback = false ) {
|
|
4240
4297
|
|
|
4241
|
-
if(
|
|
4242
|
-
this.
|
|
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
|
-
|
|
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
|
-
//
|
|
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
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
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(
|
|
4403
|
+
super.setDuration( newT, skipCallback, oldT != newT || updateHeader );
|
|
4348
4404
|
}
|
|
4349
4405
|
}
|
|
4350
4406
|
|
package/build/lexgui.css
CHANGED