From 53a604d0ccb1315576b94406cf3b0b958162307b Mon Sep 17 00:00:00 2001 From: Jon Reid Date: Fri, 27 Apr 2012 14:41:15 -0700 Subject: Timeline: Multiselect. --- .../Timeline/TimelinePanel.reel/TimelinePanel.js | 166 +++++++++++++++++++-- 1 file changed, 151 insertions(+), 15 deletions(-) (limited to 'js/panels/Timeline') diff --git a/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js b/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js index 70e04b4c..546a6abf 100644 --- a/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js +++ b/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js @@ -138,6 +138,20 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { this.cacheTimeline(); } }, + // The index of the last layer that was clicked on + // (used for shift-click multiselect) + _lastLayerClicked : { + value: 0 + }, + lastLayerClicked: { + serializable: true, + get: function() { + return this._lastLayerClicked; + }, + set: function(newVal) { + this._lastLayerClicked = newVal + } + }, _currentSelectedContainer: { value: null @@ -406,6 +420,15 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { } } }, + // is the control key currently being pressed (used for multiselect) + _isControlPressed: { + value: false + }, + + // is the shift key currently being pressed (used for multiselect) + _isShiftPressed: { + value: false + }, /* === END: Draw cycle === */ /* === BEGIN: Controllers === */ // Create an empty layer template object with minimal defaults and return it for use @@ -549,14 +572,17 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { this.layout_markers = this.element.querySelector(".layout_markers"); // Add some event handlers - this.timeline_leftpane.addEventListener("mousedown", this.timelineLeftPaneMousedown.bind(this), false); - this.timeline_leftpane.addEventListener("mouseup", this.timelineLeftPaneMouseup.bind(this), false); + //this.timeline_leftpane.addEventListener("mousedown", this.timelineLeftPanelMousedown.bind(this), false); + this.timeline_leftpane.addEventListener("click", this.timelineLeftPanelMousedown.bind(this), false); + //this.timeline_leftpane.addEventListener("mouseup", this.timelineLeftPaneMouseup.bind(this), false); this.layout_tracks.addEventListener("scroll", this.updateLayerScroll.bind(this), false); this.user_layers.addEventListener("scroll", this.updateLayerScroll.bind(this), false); this.end_hottext.addEventListener("changing", this.updateTrackContainerWidth.bind(this), false); this.playhead.addEventListener("mousedown", this.startPlayheadTracking.bind(this), false); this.playhead.addEventListener("mouseup", this.stopPlayheadTracking.bind(this), false); this.time_markers.addEventListener("click", this.updatePlayhead.bind(this), false); + document.addEventListener("keydown", this.timelineLeftPaneKeydown.bind(this), false); + document.addEventListener("keyup", this.timelineLeftPaneKeyup.bind(this), false); // Bind some bindings Object.defineBinding(this, "currentSelectedContainer", { @@ -848,15 +874,19 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { selectLayers:{ - value:function (arrSelectedIndexes) { + value:function (arrSelectedIndexes, userSelection) { var i = 0, arrLayersLength = this.arrLayers.length, arrSelectedIndexesLength = arrSelectedIndexes.length, - userSelection = false; + arrSelectedLayers = false; - //console.log(arrSelectedIndexes); + if (typeof(userSelection) === "undefined") { + userSelection = false; + } + console.log(arrSelectedIndexes); + if (this.selectedKeyframes) { this.deselectTweens(); @@ -867,9 +897,8 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { this.triggerLayerBinding(i); } - this.currentLayersSelected = false; if (arrSelectedIndexesLength > 0) { - this.currentLayersSelected = []; + arrSelectedLayers = []; } @@ -878,12 +907,18 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { this.arrLayers[i].layerData.isSelected = true; this.arrLayers[i].isSelected = true; this.triggerLayerBinding(i); - this.currentLayersSelected.push(i); + arrSelectedLayers.push(i); + + if (userSelection && this._captureSelection) { + this.application.ninja.selectionController.selectElements(this.arrLayers[i].layerData.elementsList); + } } } - + + this.currentLayersSelected = arrSelectedLayers; this.layerRepetition.selectedIndexes = arrSelectedIndexes; +/* // TODO: Set up for user selection. if (userSelection) { if (this._captureSelection) { @@ -897,7 +932,7 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { } this._captureSelection = true; } - +*/ // Finally, reset the master duration. this.resetMasterDuration(); } @@ -932,16 +967,117 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { } } - this._isMousedown = true; } }, - timelineLeftPaneMouseup:{ + timelineLeftPanelMousedown: { value:function (event) { - this._isMousedown = false; + console.log('click') + var ptrParent = nj.queryParentSelector(event.target, ".container-layer"), + i = 0, + arrLayers = document.querySelectorAll(".container-layer"), + arrLayersLength = arrLayers.length, + targetIndex = 0, + isAlreadySelected = false, + indexAlreadySelected = 0, + indexLastClicked = 0; + + // Get targetIndex, the index of the clicked target within the DOM array of layers + if (ptrParent === false) { + return; + } + for (i = 0; i < arrLayersLength; i++) { + if (arrLayers[i] == ptrParent) { + targetIndex = i; + } + } + if (this.currentLayersSelected !== false) { + indexAlreadySelected = this.currentLayersSelected.indexOf(targetIndex); + } + + if (indexAlreadySelected > -1) { + isAlreadySelected = true; + } + + if (targetIndex > -1) { + indexLastClicked = targetIndex; + } + + if (this.currentLayersSelected.length === 0) { + this.currentLayersSelected.push(targetIndex); + } else { + if (this._isControlPressed === true) { + // Control key is being pressed, so we need to + // either add the current layer to selectedLayers + // or remove it if it's already there. + if (this.currentLayersSelected === false) { + this.currentLayersSelected = []; + this.currentLayerSelected = false; + } + if (isAlreadySelected === false) { + this.currentLayersSelected.push(targetIndex); + } else { + this.currentLayersSelected.splice(indexAlreadySelected, 1); + } + this.lastLayerClicked = indexLastClicked; + } else if (this._isShiftPressed === true) { + // The shift key is being pressed. + // Start by selecting the lastLayerClicked + if (this.currentLayersSelected === false) { + this.currentLayersSelected = []; + this.currentLayerSelected = false; + } + this.currentLayersSelected = [this.lastLayerClicked]; + // Add all the layers between lastLayerClicked and targetIndex + if (targetIndex > this.lastLayerClicked) { + for (i = this.lastLayerClicked+1; i <= targetIndex; i++) { + this.currentLayersSelected.push(i); + } + } else if (targetIndex < this.lastLayerClicked) { + for (i = targetIndex; i < this.lastLayerClicked; i++) { + this.currentLayersSelected.push(i); + } + } + } else { + // No key is pressed, so just select the element + // and update lastLayerClicked + this.currentLayersSelected = [targetIndex]; + this.lastLayerClicked = targetIndex; + } + + } + this._captureSelection = true; + this.selectLayers(this.currentLayersSelected, true); } - }, - + }, + + timelineLeftPaneKeydown: { + value: function(event) { + console.log('keydown') + if (event.keyCode === 16) { + // Shift key has been pressed + this._isShiftPressed = true; + } + if (event.keyCode === 17) { + // Control key has been pressed + this._isControlPressed = true; + } + } + }, + + timelineLeftPaneKeyup: { + value: function(event) { + console.log('keyup') + if (event.keyCode === 16) { + // Shift key has been released + this._isShiftPressed = false; + } + if (event.keyCode === 17) { + // Control key has been released + this._isControlPressed = false; + } + } + }, createNewLayer:{ value:function (object) { var newLayerName = "", -- cgit v1.2.3 From e33a4e58c271a9507082694a5268b840fdd05968 Mon Sep 17 00:00:00 2001 From: Jon Reid Date: Tue, 15 May 2012 11:14:16 -0700 Subject: Timeline: Code cleanup. Improve efficiency for track scrolling. --- .../Timeline/TimelinePanel.reel/TimelinePanel.js | 72 +++++++++++----------- 1 file changed, 36 insertions(+), 36 deletions(-) (limited to 'js/panels/Timeline') diff --git a/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js b/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js index 7f4fee89..d85259cb 100644 --- a/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js +++ b/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js @@ -57,6 +57,10 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { this._layerRepetition = newVal; } }, + + _areTracksScrolling: { + value: false + }, // Set to false to skip array caching array sets in current document _boolCacheArrays:{ @@ -240,10 +244,6 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { } }, - _isLayer:{ - value:false - }, - _firstTimeLoaded:{ value:true }, @@ -370,35 +370,6 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { prepareForDraw:{ value:function () { this.initTimeline(); - // Bind the event handler for the document change events - //this.eventManager.addEventListener("onOpenDocument", this.handleDocumentChange.bind(this), false); - this.eventManager.addEventListener("closeDocument", this.handleDocumentChange.bind(this), false); - //this.eventManager.addEventListener("switchDocument", this.handleDocumentChange.bind(this), false); - //this.eventManager.addEventListener("breadCrumbBinding",this,false); - - // Bind drag and drop event handlers - this.container_layers.addEventListener("dragstart", this.handleLayerDragStart.bind(this), false); - this.container_layers.addEventListener("dragend", this.handleLayerDragEnd.bind(this), false); - this.container_layers.addEventListener("dragover", this.handleLayerDragover.bind(this), false); - this.container_layers.addEventListener("drop", this.handleLayerDrop.bind(this), false); - this.container_tracks.addEventListener("dragover", this.handleKeyframeDragover.bind(this), false); - this.container_tracks.addEventListener("drop", this.handleKeyframeDrop.bind(this), false); - - // Bind the handlers for the config menu - this.checkable_animated.addEventListener("click", this.handleAnimatedClick.bind(this), false); - this.checkable_relative.addEventListener("click", this.handleRelativeClick.bind(this), false); - this.checkable_absolute.addEventListener("click", this.handleAbsoluteClick.bind(this), false); - this.tl_configbutton.addEventListener("click", this.handleConfigButtonClick.bind(this), false); - document.addEventListener("click", this.handleDocumentClick.bind(this), false); - - } - }, - - willDraw:{ - value:function () { - if (this._isLayer) { - this._isLayer = false; - } } }, @@ -453,6 +424,14 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { this._scrollTracks = false; } } + + // Do we need to scroll the layers? + if (this._areTracksScrolling) { + this._areTracksScrolling = false; + this.user_layers.scrollTop = this.layout_tracks.scrollTop; + this.layout_markers.scrollLeft = this.layout_tracks.scrollLeft; + this.playheadmarker.style.top = this.layout_tracks.scrollTop + "px"; + } } }, @@ -597,6 +576,28 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { this.layout_tracks = this.element.querySelector(".layout-tracks"); this.layout_markers = this.element.querySelector(".layout_markers"); + + // Bind the event handler for the document change events + //this.eventManager.addEventListener("onOpenDocument", this.handleDocumentChange.bind(this), false); + this.eventManager.addEventListener("closeDocument", this.handleDocumentChange.bind(this), false); + //this.eventManager.addEventListener("switchDocument", this.handleDocumentChange.bind(this), false); + //this.eventManager.addEventListener("breadCrumbBinding",this,false); + + // Bind drag and drop event handlers + this.container_layers.addEventListener("dragstart", this.handleLayerDragStart.bind(this), false); + this.container_layers.addEventListener("dragend", this.handleLayerDragEnd.bind(this), false); + this.container_layers.addEventListener("dragover", this.handleLayerDragover.bind(this), false); + this.container_layers.addEventListener("drop", this.handleLayerDrop.bind(this), false); + this.container_tracks.addEventListener("dragover", this.handleKeyframeDragover.bind(this), false); + this.container_tracks.addEventListener("drop", this.handleKeyframeDrop.bind(this), false); + + // Bind the handlers for the config menu + this.checkable_animated.addEventListener("click", this.handleAnimatedClick.bind(this), false); + this.checkable_relative.addEventListener("click", this.handleRelativeClick.bind(this), false); + this.checkable_absolute.addEventListener("click", this.handleAbsoluteClick.bind(this), false); + this.tl_configbutton.addEventListener("click", this.handleConfigButtonClick.bind(this), false); + document.addEventListener("click", this.handleDocumentClick.bind(this), false); + // Add some event handlers this.timeline_leftpane.addEventListener("mousedown", this.timelineLeftPaneMousedown.bind(this), false); this.timeline_leftpane.addEventListener("mouseup", this.timelineLeftPaneMouseup.bind(this), false); @@ -824,9 +825,8 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { updateLayerScroll:{ value:function () { - this.user_layers.scrollTop = this.layout_tracks.scrollTop; - this.layout_markers.scrollLeft = this.layout_tracks.scrollLeft; - this.playheadmarker.style.top = this.layout_tracks.scrollTop + "px"; + this._areTracksScrolling = true; + this.needsDraw = true; } }, -- cgit v1.2.3 From 26f1524c049791cb9cd81695c57b84d952a2e7e6 Mon Sep 17 00:00:00 2001 From: Jon Reid Date: Tue, 15 May 2012 16:08:26 -0700 Subject: Timeline: Multiselect from the layer panel. --- js/panels/Timeline/Layer.reel/Layer.js | 12 +- js/panels/Timeline/Layer.reel/css/Layer.css | 75 ++++----- js/panels/Timeline/Layer.reel/scss/Layer.scss | 5 +- .../Timeline/TimelinePanel.reel/TimelinePanel.js | 184 +++++++++------------ 4 files changed, 131 insertions(+), 145 deletions(-) (limited to 'js/panels/Timeline') diff --git a/js/panels/Timeline/Layer.reel/Layer.js b/js/panels/Timeline/Layer.reel/Layer.js index b0f6d220..418d2226 100644 --- a/js/panels/Timeline/Layer.reel/Layer.js +++ b/js/panels/Timeline/Layer.reel/Layer.js @@ -494,10 +494,14 @@ var Layer = exports.Layer = Montage.create(Component, { }, draw: { value: function() { - if (this.isSelected) { - this.element.classList.add("selected"); - } else { - this.element.classList.remove("selected"); + var boolHasClass = this.element.classList.contains("layerSelected"); + if (this.isSelected && !boolHasClass) { + //console.log('Layer.draw, adding selection for layer ', this.layerName) + this.element.classList.add("layerSelected"); + } + if (!this.isSelected && boolHasClass) { + //console.log('Layer.draw, removing selection for layer ', this.layerName) + this.element.classList.remove("layerSelected"); } } }, diff --git a/js/panels/Timeline/Layer.reel/css/Layer.css b/js/panels/Timeline/Layer.reel/css/Layer.css index 3648fda5..788a786e 100644 --- a/js/panels/Timeline/Layer.reel/css/Layer.css +++ b/js/panels/Timeline/Layer.reel/css/Layer.css @@ -71,26 +71,27 @@ } /******************************************/ -/* line 77, ../scss/Layer.scss */ -.container-layer { +/* line 78, ../scss/Layer.scss */ +.container-layer, +.container-layer.selected { background-color: #474747; color: white; font-size: 12px; text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5); } -/* line 83, ../scss/Layer.scss */ +/* line 84, ../scss/Layer.scss */ .selected .container-layer { background-color: #474747; } -/* line 86, ../scss/Layer.scss */ +/* line 87, ../scss/Layer.scss */ .selected .container-layer .label-layer { background-color: #b2b2b2; color: #242424; } -/* line 91, ../scss/Layer.scss */ +/* line 92, ../scss/Layer.scss */ .userlayers .collapsible-label { display: block; height: 21px; @@ -103,32 +104,32 @@ text-overflow: ellipsis; } -/* line 103, ../scss/Layer.scss */ +/* line 104, ../scss/Layer.scss */ .userlayers .layer-tag { position: absolute; top: 3px; left: 20px; } -/* line 110, ../scss/Layer.scss */ +/* line 111, ../scss/Layer.scss */ .layerSelected .label-layer { background-color: #b2b2b2; color: #242424; } -/* line 114, ../scss/Layer.scss */ +/* line 115, ../scss/Layer.scss */ .content-layer { background-color: #474747; color: white; } -/* line 118, ../scss/Layer.scss */ +/* line 119, ../scss/Layer.scss */ .content-layer .collapsible-label { background-position: 14px 5px; border-width: 0px; } -/* line 126, ../scss/Layer.scss */ +/* line 127, ../scss/Layer.scss */ .label-layer, .label-position, .label-transform, @@ -139,20 +140,20 @@ cursor: pointer; } -/* line 134, ../scss/Layer.scss */ +/* line 135, ../scss/Layer.scss */ .content-layer .collapsible-label, .content-layer .collapsible-content, .content-layer .layer-tag { font-size: 11px; } -/* line 141, ../scss/Layer.scss */ +/* line 142, ../scss/Layer.scss */ .label-layer .collapsible-label br, .content-style .editable br { display: none; } -/* line 145, ../scss/Layer.scss */ +/* line 146, ../scss/Layer.scss */ .collapsible-clicker { position: absolute; width: 10px; @@ -165,23 +166,23 @@ background-repeat: no-repeat; } -/* line 156, ../scss/Layer.scss */ +/* line 157, ../scss/Layer.scss */ .collapsible-clicker.collapsible-collapsed { background-image: url(../images/icon-collapsed.png); } -/* line 159, ../scss/Layer.scss */ +/* line 160, ../scss/Layer.scss */ .collapsible-content .collapsible-clicker { left: 12px; } -/* line 162, ../scss/Layer.scss */ +/* line 163, ../scss/Layer.scss */ .container-layer .collapsible-content.collapsible-collapsed { height: 0px; overflow: hidden; } -/* line 168, ../scss/Layer.scss */ +/* line 169, ../scss/Layer.scss */ .label-layer .cssbutton, .label-style .cssbutton { width: 14px; @@ -191,21 +192,21 @@ background-repeat: no-repeat; } -/* line 175, ../scss/Layer.scss */ +/* line 176, ../scss/Layer.scss */ .label-layer .button-lock { background-image: url(../images/icon-lock.png); top: 3px; right: 27px; } -/* line 180, ../scss/Layer.scss */ +/* line 181, ../scss/Layer.scss */ .label-layer .button-visible { background-image: url(../images/icon-eye.png); top: 3px; right: 7px; } -/* line 185, ../scss/Layer.scss */ +/* line 186, ../scss/Layer.scss */ .label-style .button-add { background-image: url(../images/icon-plus.png); width: 15px; @@ -214,7 +215,7 @@ right: 11px; } -/* line 192, ../scss/Layer.scss */ +/* line 193, ../scss/Layer.scss */ .label-style .button-delete { background-image: url(../images/icon-minus.png); width: 15px; @@ -223,28 +224,28 @@ right: 31px; } -/* line 199, ../scss/Layer.scss */ +/* line 200, ../scss/Layer.scss */ .timeline-track .collapsible-content { position: relative; } -/* line 202, ../scss/Layer.scss */ +/* line 203, ../scss/Layer.scss */ .collapsible-content .layout-table { width: 99.9%; } -/* line 205, ../scss/Layer.scss */ +/* line 206, ../scss/Layer.scss */ .content-layer .collapsible-content { padding-left: 30px; } -/* line 208, ../scss/Layer.scss */ +/* line 209, ../scss/Layer.scss */ .collapsible-content .collapsible-content .layout-table .layout-row { height: 20px; overflow: hidden; } -/* line 212, ../scss/Layer.scss */ +/* line 213, ../scss/Layer.scss */ .collapsible-content .collapsible-content .layout-table .layout-row .layout-cell { width: 40%; height: 20px; @@ -254,13 +255,13 @@ overflow: hidden; } -/* line 221, ../scss/Layer.scss */ +/* line 222, ../scss/Layer.scss */ .collapsible-content .collapsible-content .container-row { border-bottom: 1px solid #505050; height: 20px; } -/* line 227, ../scss/Layer.scss */ +/* line 228, ../scss/Layer.scss */ .collapsible-content .collapsible-content .cell-property, .collapsible-content .collapsible-content .cell-value { width: 45%; @@ -272,24 +273,24 @@ line-height: 18px; } -/* line 239, ../scss/Layer.scss */ +/* line 240, ../scss/Layer.scss */ .collapsible-content .layout-table:first-child { border-top: 1px solid #505050; } -/* line 243, ../scss/Layer.scss */ +/* line 244, ../scss/Layer.scss */ .collapsible-content .hottextunit { width: auto; } -/* line 246, ../scss/Layer.scss */ +/* line 247, ../scss/Layer.scss */ .collapsible-transition { -webkit-transition-property: height; -webkit-transition-duration: 200ms; -webkit-transition-timing-function: ease-in; } -/* line 254, ../scss/Layer.scss */ +/* line 255, ../scss/Layer.scss */ .editable2 { height: 20px; background-color: #242424 !important; @@ -301,29 +302,29 @@ text-overflow: clip; } -/* line 264, ../scss/Layer.scss */ +/* line 265, ../scss/Layer.scss */ .editable2 br { display: inline; } -/* line 268, ../scss/Layer.scss */ +/* line 269, ../scss/Layer.scss */ .label-style .disabled { cursor: default; } /* styles elements */ -/* line 273, ../scss/Layer.scss */ +/* line 274, ../scss/Layer.scss */ .content-style .item-template { display: none; } -/* line 276, ../scss/Layer.scss */ +/* line 277, ../scss/Layer.scss */ .content-style .layout-row.selected .layout-cell { background-color: #b2b2b2; color: #242424; } -/* line 280, ../scss/Layer.scss */ +/* line 281, ../scss/Layer.scss */ .style-row { height: 20px; } diff --git a/js/panels/Timeline/Layer.reel/scss/Layer.scss b/js/panels/Timeline/Layer.reel/scss/Layer.scss index a407c9dc..8f8881dd 100644 --- a/js/panels/Timeline/Layer.reel/scss/Layer.scss +++ b/js/panels/Timeline/Layer.reel/scss/Layer.scss @@ -74,7 +74,8 @@ /******************************************/ -.container-layer { +.container-layer, +.container-layer.selected { background-color: $color-panel-bg; color: $color-panel-text; font-size: 12px; @@ -108,7 +109,7 @@ .layerSelected .label-layer { - background-color: $color-panel-hilite-bg; + background-color: $color-menu-hilite-bg; color: $color-panel-hilite-text; } .content-layer { diff --git a/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js b/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js index 767dc362..f6e0e252 100644 --- a/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js +++ b/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js @@ -95,6 +95,18 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { this.cacheTimeline(); } }, + _currentElementsSelected: { + value: [] + }, + currentElementsSelected: { + get: function() { + return this._currentElementsSelected; + }, + set: function(newVal) { + this._currentElementsSelected = newVal; + this.cacheTimeline(); + } + }, _selectedLayerID:{ value:false @@ -506,6 +518,7 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { this.application.ninja.currentDocument.tllayerNumber = this.currentLayerNumber; this.application.ninja.currentDocument.tlCurrentLayerSelected = this.currentLayerSelected; this.application.ninja.currentDocument.tlCurrentLayersSelected = this.currentLayersSelected; + this.application.ninja.currentDocument.tlCurrentElementsSelected = this.currentElementsSelected; } } }, @@ -519,6 +532,7 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { this.application.ninja.currentDocument.tllayerNumber = this.currentLayerNumber; this.application.ninja.currentDocument.tlCurrentLayerSelected = false; this.application.ninja.currentDocument.tlCurrentLayersSelected = false; + this.application.ninja.currentDocument.tlCurrentElementsSelected = []; } }, @@ -622,8 +636,8 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { document.addEventListener("click", this.handleDocumentClick.bind(this), false); // Add some event handlers - //this.timeline_leftpane.addEventListener("mousedown", this.timelineLeftPanelMousedown.bind(this), false); - this.timeline_leftpane.addEventListener("click", this.timelineLeftPanelMousedown.bind(this), false); + this.timeline_leftpane.addEventListener("mousedown", this.timelineLeftPanelMousedown.bind(this), false); + //this.timeline_leftpane.addEventListener("click", this.timelineLeftPanelMousedown.bind(this), false); //this.timeline_leftpane.addEventListener("mouseup", this.timelineLeftPaneMouseup.bind(this), false); this.layout_tracks.addEventListener("scroll", this.updateLayerScroll.bind(this), false); this.user_layers.addEventListener("scroll", this.updateLayerScroll.bind(this), false); @@ -708,8 +722,6 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { this.currentLayerNumber = storedCurrentLayerNumber; boolAlreadyInitialized = true; this.application.ninja.currentDocument.setLevel = false; - - } else { //console.log('TimelinePanel.initTimelineForDocument: else fallback'); // we do have information stored. Use it. @@ -729,6 +741,7 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { this.currentLayerNumber = this.application.ninja.currentDocument.tllayerNumber; this.currentLayerSelected = this.application.ninja.currentDocument.tlCurrentLayerSelected; this.currentLayersSelected = this.application.ninja.currentDocument.tlCurrentLayersSelected; + this.currentElementsSelected = this.application.ninja.currentDocument.tlCurrentElementsSelected; this._currentDocumentUuid = this.application.ninja.currentDocument.uuid; @@ -737,6 +750,8 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { // this.application.ninja.currentSelectedContainer=this.application.ninja.currentDocument.tlCurrentSelectedContainer; } + // TODO: select elements stored in currentElementsSelected. + // Are we only showing animated layers? if (this.application.ninja.currentDocument.boolShowOnlyAnimated) { // Fake a click. @@ -773,6 +788,7 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { this.currentLayerNumber = 0; this.currentLayerSelected = false; this.currentLayersSelected = false; + this.currentElementsSelected = []; this.selectedKeyframes = []; this.selectedTweens = []; this._captureSelection = false; @@ -878,7 +894,7 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { this.updateTimeText(currentMillisec); } }, - + handleSelectionChange:{ value:function () { var layerIndex, @@ -887,7 +903,7 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { arrLayersLength = this.arrLayers.length, intNumSelected = this.application.ninja.selectedElements.length, checkIndex = 0; - + //console.log("TimelinePanel.handleSelectionChange, intNumSelected is ", intNumSelected) if (intNumSelected === 0) { @@ -899,30 +915,10 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { this.currentLayerSelected = false; this.currentLayersSelected = false; - } - - if (intNumSelected === 1) { - this.currentLayersSelected = false; - if (this.application.ninja.selectedElements[0]) { - checkIndex = this.application.ninja.selectedElements[0].uuid; - for (i = 0; i < arrLayersLength; i++) { - var currIndex = this.arrLayers[i].layerData.elementsList[0].uuid, - layerID = this.arrLayers[i].layerData.layerID, - layerIndex = 0; - if (checkIndex === currIndex) { - layerIndex = this.getLayerIndexByID(layerID); - this._captureSelection = false; - this.selectLayer(layerIndex); - this._captureSelection = true; - } - } - } - } - - if (intNumSelected > 1) { + } else { // Build an array of indexes of selected layers to give to the selectLayers method var arrSelectedIndexes = []; - this.currentLayerSelected = false; + //this.currentLayerSelected = false; for (i = 0; i < intNumSelected; i++) { var currentCheck = this.application.ninja.selectedElements[i].uuid; //console.log("checking ", currentCheck); @@ -939,71 +935,71 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { } }, - - selectLayers:{ value:function (arrSelectedIndexes, userSelection) { var i = 0, arrLayersLength = this.arrLayers.length, arrSelectedIndexesLength = arrSelectedIndexes.length, - arrSelectedLayers = false; + arrSelectedLayers = false, + arrCurrentElementsSelected = []; - if (typeof(userSelection) === "undefined") { + // Set a default for userSelection if it wasn't passed in the method call. + if (typeof(userSelection) === "undefined") { userSelection = false; } - - console.log(arrSelectedIndexes); - - if (this.selectedKeyframes) { + // Deselect tweens if necessary. + if (this.selectedKeyframes) { this.deselectTweens(); } + // deselect all layers. for (i = 0; i < arrLayersLength; i++) { - this.arrLayers[i].layerData.isSelected = false; - this.triggerLayerBinding(i); + if (this.arrLayers[i].layerData.isSelected === true) { + this.arrLayers[i].layerData.isSelected = false; + this.triggerLayerBinding(i); + } } - if (this.currentLayersSelected !== false) { this.currentLayersSelected = false; } + + // If we are actually going to be selecting things, create an empty array to use if (arrSelectedIndexesLength > 0) { arrSelectedLayers = []; } - + // Loop through arrLayers and do the selection. for (i = 0; i < arrLayersLength; i++) { if (arrSelectedIndexes.indexOf(i) > -1) { + //console.log('TimelinePanel.selectLayers, selecting layer at index ', i) this.arrLayers[i].layerData.isSelected = true; this.arrLayers[i].isSelected = true; this.triggerLayerBinding(i); arrSelectedLayers.push(i); - - if (userSelection && this._captureSelection) { - this.application.ninja.selectionController.selectElements(this.arrLayers[i].layerData.elementsList); - } + arrCurrentElementsSelected.push(this.arrLayers[i].layerData.elementsList[0]); } } - - this.currentLayersSelected = arrSelectedLayers; - this.layerRepetition.selectedIndexes = arrSelectedIndexes; + -/* - // TODO: Set up for user selection. - if (userSelection) { - if (this._captureSelection) { + // Select the element(s) on the stage. + if (userSelection && this._captureSelection) { + if (this.currentElementsSelected.length >0) { + this.application.ninja.selectionController.selectElements(arrCurrentElementsSelected); + } else { + this.application.ninja.selectionController.executeSelectElement(); + } + + } - if (this.currentLayerSelected.layerData.elementsList.length >= 1) { - this.application.ninja.selectionController.selectElements(this.currentLayerSelected.layerData.elementsList); - } else { - this.application.ninja.selectionController.executeSelectElement(); - } + // Store the selected layer information + this.currentLayersSelected = arrSelectedLayers; + this.currentElementsSelected = arrCurrentElementsSelected; + + // Tell the repetition what has been selected + this.layerRepetition.selectedIndexes = arrSelectedIndexes; - } - this._captureSelection = true; - } -*/ // Finally, reset the master duration. this.resetMasterDuration(); } @@ -1019,22 +1015,8 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { } }, - timelineLeftPaneMousedown:{ - value:function (event) { - var ptrParent = nj.queryParentSelector(event.target, ".container-layer"); - if (ptrParent !== false) { - var myIndex = this.getActiveLayerIndex(); - if (myIndex !== false) { - this.selectLayer(myIndex, true); - } - - } - } - }, - timelineLeftPanelMousedown: { value:function (event) { - console.log('click') var ptrParent = nj.queryParentSelector(event.target, ".container-layer"), i = 0, arrLayers = document.querySelectorAll(".container-layer"), @@ -1044,50 +1026,61 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { indexAlreadySelected = 0, indexLastClicked = 0; - // Get targetIndex, the index of the clicked target within the DOM array of layers + // Did the mousedown event originate within a layer? if (ptrParent === false) { + // No it did not. Do nothing. return; } + + // Get the targetIndex, the index in the arrLayers of the + // layer that was just clicked on for (i = 0; i < arrLayersLength; i++) { if (arrLayers[i] == ptrParent) { targetIndex = i; } } + + // Did we just click on a layer that's already selected? if (this.currentLayersSelected !== false) { indexAlreadySelected = this.currentLayersSelected.indexOf(targetIndex); } - if (indexAlreadySelected > -1) { isAlreadySelected = true; } + /* if (targetIndex > -1) { indexLastClicked = targetIndex; } + */ + // Now, do the selection based on all of that information. if (this.currentLayersSelected.length === 0) { + // Nothing selected yet, so just push the new index into the array. this.currentLayersSelected.push(targetIndex); } else { + // Something is already selected. What do do depends on whether + // or not other keys are pressed. if (this._isControlPressed === true) { // Control key is being pressed, so we need to // either add the current layer to selectedLayers // or remove it if it's already there. if (this.currentLayersSelected === false) { this.currentLayersSelected = []; - this.currentLayerSelected = false; + //this.currentLayerSelected = false; } if (isAlreadySelected === false) { this.currentLayersSelected.push(targetIndex); } else { this.currentLayersSelected.splice(indexAlreadySelected, 1); } - this.lastLayerClicked = indexLastClicked; + this.lastLayerClicked = targetIndex; } else if (this._isShiftPressed === true) { // The shift key is being pressed. // Start by selecting the lastLayerClicked if (this.currentLayersSelected === false) { this.currentLayersSelected = []; - this.currentLayerSelected = false; + //this.currentLayerSelected = false; } this.currentLayersSelected = [this.lastLayerClicked]; // Add all the layers between lastLayerClicked and targetIndex @@ -1115,7 +1108,6 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { timelineLeftPaneKeydown: { value: function(event) { - console.log('keydown') if (event.keyCode === 16) { // Shift key has been pressed this._isShiftPressed = true; @@ -1129,7 +1121,6 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { timelineLeftPaneKeyup: { value: function(event) { - console.log('keyup') if (event.keyCode === 16) { // Shift key has been released this._isShiftPressed = false; @@ -1201,7 +1192,7 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { this.arrLayers.splice(myIndex, 0, thingToPush); } - this.selectLayer(myIndex); + this.selectLayers([myIndex]); } }, @@ -1244,7 +1235,7 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { deleteLayer:{ value:function (arrElements) { - // Only delete a selected layers. If no layers are selected, do nothing. + // Only delete selected layers. If no layers are selected, do nothing. var i = 0, arrLayers = document.querySelectorAll(".container-layers .container-layer"), arrLayersLength = arrLayers.length; @@ -1257,26 +1248,9 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { this.currentLayerSelected = false; this.currentLayersSelected = false; + this.selectedElements = []; this.resetMasterDuration(); - - - /* - var length = elements.length; - - while(length>0){ - if (this.layerRepetition.selectedIndexes.length > 0) { - // Delete the selected layer. - var myIndex = this.layerRepetition.selectedIndexes[0]; - this.arrLayers.splice(myIndex, 1); - var selectIndex = this.arrLayers.length; - this.resetMasterDuration(); - if(selectIndex>0){ - this.selectLayer(selectIndex-1); - } - length--; - } - } - */ + } }, @@ -1309,6 +1283,10 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { this.currentLayerSelected.layerData.elementsList = []; } this.currentLayerSelected.layerData.elementsList.push(this.application.ninja.selectedElements[0]); + + // TODO: verify this is correct. + this.selectedElements = []; + this.selectedElements.push(this.application.ninja.selectedElements[0]); // this.currentLayerSelected.layerData.elementsList[0].dataset.storedLayerName = this.currentLayerSelected.layerData.layerName; } }, @@ -1432,6 +1410,8 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { selectLayer:{ value:function (layerIndex, userSelection) { +console.log('TimelinePanel.selectLayer') + var i = 0; var arrLayersLength = this.arrLayers.length; -- cgit v1.2.3 From a696dffcc84b4d2719f8fa918676f9575858ca9a Mon Sep 17 00:00:00 2001 From: Jon Reid Date: Thu, 17 May 2012 16:52:16 -0700 Subject: Timeline: Multiselect improvements. New convenience methods. Multiselect drag and drop. --- js/panels/Timeline/Layer.reel/Layer.js | 19 +- .../Timeline/TimelinePanel.reel/TimelinePanel.js | 329 ++++++++++++++++++--- .../Timeline/TimelineTrack.reel/TimelineTrack.js | 16 +- 3 files changed, 319 insertions(+), 45 deletions(-) (limited to 'js/panels/Timeline') diff --git a/js/panels/Timeline/Layer.reel/Layer.js b/js/panels/Timeline/Layer.reel/Layer.js index 418d2226..4a737490 100644 --- a/js/panels/Timeline/Layer.reel/Layer.js +++ b/js/panels/Timeline/Layer.reel/Layer.js @@ -133,6 +133,20 @@ var Layer = exports.Layer = Montage.create(Component, { } }, + _stageElement: { + value: null + }, + + stageElement: { + get: function() { + return this._stageElement; + }, + set: function(newVal) { + this._stageElement = newVal; + this.layerData.stageElement = newVal; + } + }, + _elementsList : { value: [] @@ -398,6 +412,7 @@ var Layer = exports.Layer = Montage.create(Component, { this.layerName = this.layerData.layerName; this.layerID = this.layerData.layerID; + this.stageElement = this.layerData.stageElement this.arrLayerStyles = this.layerData.arrLayerStyles; this.isMainCollapsed = this.layerData.isMainCollapsed; this.isPositionCollapsed = this.layerData.isPositionCollapsed; @@ -678,7 +693,7 @@ var Layer = exports.Layer = Montage.create(Component, { this.dynamicLayerName.value = this._layerEditable.value; this.needsDraw = true; this.application.ninja.documentController.activeDocument.needsSave = true; - this.layerData.elementsList[0].setAttribute("id",this.dynamicLayerName.value); + this.layerData.stageElement.setAttribute("id",this.dynamicLayerName.value); } }, handleAddStyleClick: { @@ -790,7 +805,7 @@ var Layer = exports.Layer = Montage.create(Component, { }, handleDragstart: { value: function(event) { - this.parentComponent.parentComponent.dragLayerID = this.layerID; + //this.parentComponent.parentComponent.dragLayerID = this.layerID; event.dataTransfer.setData('Text', 'Layer'); this.parentComponent.parentComponent.draggingType = "layer"; } diff --git a/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js b/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js index f6e0e252..1ddb3977 100644 --- a/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js +++ b/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js @@ -326,6 +326,9 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { } } }, + _dragLayerIndexes: { + value: [] + }, _dropLayerID : { value: null }, @@ -337,6 +340,38 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { if (newVal !== this._dropLayerID) { this._dropLayerID = newVal; + var dropLayerIndex = this.getLayerIndexByID(this.dropLayerID), + arrDragLayers = [], + i = 0, + dragLayerIndexesLength = this._dragLayerIndexes.length; + + // TODO: possibly we'll need to sort dragLayerIndexes so things don't get out of order? + + for (i = 0; i < dragLayerIndexesLength; i++) { + var myDraggingLayer = this.arrLayers[this._dragLayerIndexes[i]]; + arrDragLayers.push(myDraggingLayer); + this.arrLayers.splice(this._dragLayerIndexes[i], 1); + this.arrLayers.splice(dropLayerIndex, 0, myDraggingLayer); + } + console.log(arrDragLayers); + //this.arrLayers.splice(dropLayerIndex, 0, arrDragLayers); + this.layersDragged = arrDragLayers; + console.log(this.layersDragged); + console.log(this.arrLayers); + this._layerDroppedInPlace = this.arrLayers[dropLayerIndex]; + this.cacheTimeline(); + + this._dropLayerID = null; + this.dragLayerIndexes = []; + this._dragLayerIndexes = []; + this.lastLayerClicked = 0; + + // Sometimes, just to be fun, the drop and dragend events don't fire. + // So just in case, set the draw routine to delete the helper. + this._deleteHelper = true; + this.needsDraw = true; + +/* var dragLayerIndex = this.getLayerIndexByID(this.dragLayerID), dropLayerIndex = this.getLayerIndexByID(this.dropLayerID), dragLayer = this.arrLayers[dragLayerIndex]; @@ -355,6 +390,7 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { // So just in case, set the draw routine to delete the helper. this._deleteHelper = true; this.needsDraw = true; +*/ } } }, @@ -480,6 +516,7 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { returnObj.layerData = {}; returnObj.layerData.layerName = null; returnObj.layerData.layerID = null; + returnObj.layerData.stageElement = null; returnObj.layerData.isMainCollapsed = true; returnObj.layerData.isPositionCollapsed = true; returnObj.layerData.isTransformCollapsed = true; @@ -584,7 +621,7 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { // Bind all document-specific events (pass in true to unbind) _bindDocumentEvents : { value: function(boolUnbind) { - var arrEvents = [ "newLayer", + var arrEvents = [ "stageElement", "deleteLayer", "elementAdded", "elementsRemoved", @@ -895,13 +932,16 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { } }, - handleSelectionChange:{ - value:function () { + // Event handler for changes in stage selection. + handleSelectionChange: { + value:function (event) { + this.updateLayerSelection(); + /* var layerIndex, i = 0, j = 0, arrLayersLength = this.arrLayers.length, - intNumSelected = this.application.ninja.selectedElements.length, + intNumSelected = event.detail.elements.length, checkIndex = 0; //console.log("TimelinePanel.handleSelectionChange, intNumSelected is ", intNumSelected) @@ -919,12 +959,17 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { // Build an array of indexes of selected layers to give to the selectLayers method var arrSelectedIndexes = []; //this.currentLayerSelected = false; + + //console.log(event.detail.elements); + //console.log(this.layerRepetition.childComponents); + for (i = 0; i < intNumSelected; i++) { - var currentCheck = this.application.ninja.selectedElements[i].uuid; + var currentCheck = event.detail.elements[i]; //console.log("checking ", currentCheck); for (j = 0; j < arrLayersLength; j++) { - //console.log(".......... ", this.arrLayers[j].layerData.elementsList[0].uuid) - if (currentCheck === this.arrLayers[j].layerData.elementsList[0].uuid) { + //console.log(".......... ", this.arrLayers[j].layerData.stageElement) + // if (currentCheck === this.arrLayers[j].layerData.elementsList[0].uuid) { + if (currentCheck === this.arrLayers[j].layerData.stageElement) { //console.log("...............Yes!") arrSelectedIndexes.push(j); } @@ -932,17 +977,120 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { } this.selectLayers(arrSelectedIndexes); } + */ } }, + // Select the layers whose indexes are passed in as arrSelectedIndexes. + // Pass in an empty array to clear all selections. selectLayers:{ - value:function (arrSelectedIndexes, userSelection) { + value:function (arrSelectedIndexes) { + var i = 0, + j = 0, + arrLayersLength = this.arrLayers.length, + arrSelectedIndexesLength = arrSelectedIndexes.length, + currentLayersSelectedLength = this.currentLayersSelected.length, + boolContinue = false, + arrSelectedLayers = false, + arrCurrentElementsSelected = []; + /* + console.log(arrSelectedIndexes); + console.log(this.currentLayersSelected); + // Compare arrSelectedIndexes with this.currentLayersSelected + // If the items are the same, we do not need to do anything. + if (arrSelectedIndexesLength !== currentLayersSelectedLength) { + // Different length in the arrays, we definitely need to continue. + console.log('diferent length') + boolContinue = true; + } else { + // Check each selected index and see if it's in this.currentLayersSelected + // If we find one that isn't, we need to continue + + for (i = 0; i < arrSelectedIndexesLength; i++) { + console.log('checking for ', arrSelectedIndexes[i]); + if (this.currentLayersSelected.indexOf(arrSelectedIndexes[i]) === -1) { + // Ooops, one of them was not found. + boolContinue = true; + } + } + } + if (boolContinue === false) { + console.log('exiting') + return; + } + */ + + // Deselect all layers. + for (i = 0; i < arrLayersLength; i++) { + if (this.arrLayers[i].layerData.isSelected === true) { + this.arrLayers[i].layerData.isSelected = false; + this.triggerLayerBinding(i); + } + } + if (this.currentLayersSelected !== false) { + this.currentLayersSelected = false; + } + + // If we are actually going to be selecting things, create an empty array to use + if (arrSelectedIndexesLength > 0) { + arrSelectedLayers = []; + } + + // Loop through arrLayers and do the selection. + for (i = 0; i < arrLayersLength; i++) { + if (arrSelectedIndexes.indexOf(i) > -1) { + //console.log('TimelinePanel.selectLayers, selecting layer at index ', i) + this.arrLayers[i].layerData.isSelected = true; + this.arrLayers[i].isSelected = true; + this.triggerLayerBinding(i); + arrSelectedLayers.push(i); + arrCurrentElementsSelected.push(this.arrLayers[i].layerData.stageElement); + } + } + + // Store the selected layer information + this.currentLayersSelected = arrSelectedLayers; + this.currentElementsSelected = arrCurrentElementsSelected; + + // Tell the repetition what has been selected + this.layerRepetition.selectedIndexes = arrSelectedIndexes; + + // Finally, reset the master duration. + this.resetMasterDuration(); + +/* var i = 0, + j = 0, arrLayersLength = this.arrLayers.length, arrSelectedIndexesLength = arrSelectedIndexes.length, + currentElementsSelectedLength = this.currentElementsSelected.length, + boolUpdate = false, arrSelectedLayers = false, arrCurrentElementsSelected = []; + + + // Only run if arrSelectedIndexes has things that aren't already selected. + if (arrSelectedIndexesLength !== currentElementsSelectedLength) { + // If the two arrays are different lengths, then we need to update + boolUpdate = true; + } else { + // If arrSelectedIndexes has things in it that aren't present in this.currentElementsSelected + // we need to update + for (i = 0; i < arrSelectedIndexesLength; i++) { + var boolWasIFound = false; + for (j = 0; j < currentElementsSelectedLength; j++) { + + } + if (boolWasIFound === false) { + boolUpdate = true; + } + } + } + if (boolUpdate === false) { + return; + } + // Set a default for userSelection if it wasn't passed in the method call. if (typeof(userSelection) === "undefined") { @@ -1002,8 +1150,64 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { // Finally, reset the master duration. this.resetMasterDuration(); +*/ } }, + + // Get the indexes of layers that should be selected from + // the elements that are currently selected on stage. + getSelectedLayerIndexesFromStage: { + value: function() { + var arrIndexes = [], + i = 0, + j = 0, + arrLayersLength = this.arrLayers.length, + selectedElementsLength = this.application.ninja.selectedElements.length; + + for (i = 0; i < selectedElementsLength; i++) { + var currentTestElement = this.application.ninja.selectedElements[i]; + for (j = 0; j < arrLayersLength; j++) { + if (this.arrLayers[j].layerData.stageElement == currentTestElement) { + arrIndexes.push(j); + } + } + } + return arrIndexes; + } + }, + + // Update the selected layers based on what is selected on stage + updateLayerSelection: { + value: function() { + var arrIndexes = this.getSelectedLayerIndexesFromStage(); + this.selectLayers(arrIndexes); + } + }, + + // Update stage selection based on what layers are selected + updateStageSelection: { + value: function() { + var arrSelectedElements = [], + i = 0, + arrLayersLength = this.arrLayers.length; + + // Get the selected layers + for (i = 0; i < arrLayersLength; i++) { + if (this.arrLayers[i].layerData.isSelected === true) { + arrSelectedElements.push(this.arrLayers[i].layerData.stageElement); + } + } + + // Select the layers, or clear the selection if none were found + if (arrSelectedElements.length > 0) { + console.log("TimelinePanel.updateStageSelection, ", arrSelectedElements) + this.application.ninja.selectionController.selectElements(arrSelectedElements); + } else { + this.application.ninja.selectionController.executeSelectElement(); + } + + } + }, deselectTweens:{ value:function () { @@ -1025,7 +1229,8 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { isAlreadySelected = false, indexAlreadySelected = 0, indexLastClicked = 0; - + + console.log(ptrParent); // Did the mousedown event originate within a layer? if (ptrParent === false) { // No it did not. Do nothing. @@ -1101,8 +1306,9 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { } } - this._captureSelection = true; - this.selectLayers(this.currentLayersSelected, true); + //this._captureSelection = true; + this.selectLayers(this.currentLayersSelected); + this.updateStageSelection(); } }, @@ -1131,9 +1337,9 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { } } }, - createNewLayer:{ + createstageElement:{ value:function (object) { - var newLayerName = "", + var stageElementName = "", thingToPush = this.createLayerTemplate(), myIndex = 0, i = 0, @@ -1141,16 +1347,16 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { // Make up a layer name. this.currentLayerNumber = this.currentLayerNumber + 1; -// newLayerName = "Layer " + this.currentLayerNumber; - newLayerName=" "; +// stageElementName = "Layer " + this.currentLayerNumber; + stageElementName=" "; // Possibly currentLayerNumber doesn't correctly reflect the // number of layers. Check that. // Commented out to fix WebGL rendering bug /*for(k = 0; k < arrLayersLength; k++){ - if(this.arrLayers[k].layerData.layerName === newLayerName){ + if(this.arrLayers[k].layerData.layerName === stageElementName){ this.currentLayerNumber = this.currentLayerNumber + 1; - newLayerName = "Layer " + this.currentLayerNumber; + stageElementName = "Layer " + this.currentLayerNumber; break; } }*/ @@ -1159,14 +1365,15 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { this.currentLayersSelected = false; // thingToPush is the template we just got. Now fill it in. - thingToPush.layerData.layerName = newLayerName; + thingToPush.layerData.layerName = stageElementName; thingToPush.layerData.layerTag = "<" + object.nodeName.toLowerCase() + ">"; thingToPush.layerData.layerID = this.currentLayerNumber; thingToPush.parentElement = this.application.ninja.currentSelectedContainer; thingToPush.layerData.isSelected = true; thingToPush.layerData._isFirstDraw = true; thingToPush.layerData.created = true; - + thingToPush.layerData.stageElement = object; + if (this.checkable_animated.classList.contains("checked")) { thingToPush.layerData.isVisible = false; } @@ -1199,13 +1406,14 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { restoreLayer:{ value:function (ele) { - var newLayerName, thingToPush = this.createLayerTemplate(); + var stageElementName, + thingToPush = this.createLayerTemplate(); this.currentLayerNumber = this.currentLayerNumber + 1; -// newLayerName = "Layer " + this.currentLayerNumber; +// stageElementName = "Layer " + this.currentLayerNumber; // if(ele.dataset.storedLayerName){ -// newLayerName = ele.dataset.storedLayerName; +// stageElementName = ele.dataset.storedLayerName; // } if(ele.id){ thingToPush.layerData.layerName = ele.id; @@ -1213,17 +1421,19 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { thingToPush.layerData.layerID = this.currentLayerNumber; thingToPush.layerData.layerTag = "<" + ele.nodeName.toLowerCase() + ">"; thingToPush.parentElement = this.application.ninja.currentSelectedContainer; + if (this._openDoc) { + //thingToPush.layerData.elementsList.push(ele); + thingToPush.layerData.stageElement = ele; + } if (this.checkable_animated.classList.contains("checked")) { thingToPush.layerData.isVisible = false; } + // Are there styles to add? thingToPush.layerData.arrLayerStyles = this.createLayerStyles(); thingToPush.layerData.arrStyleTracks = this.createStyleTracks(); - if (this._openDoc) { - thingToPush.layerData.elementsList.push(ele); - } - + // Add the layer to the repetition this.temparrLayers.splice(0, 0, thingToPush); thingToPush.layerData.trackPosition = this.temparrLayers.length - 1; thingToPush.layerData.layerPosition = this.temparrLayers.length - 1; @@ -1236,6 +1446,7 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { deleteLayer:{ value:function (arrElements) { // Only delete selected layers. If no layers are selected, do nothing. + // TODO: maybe this should use this.selectedElements instead of a call to querySelectorAll. var i = 0, arrLayers = document.querySelectorAll(".container-layers .container-layer"), arrLayersLength = arrLayers.length; @@ -1253,6 +1464,26 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { } }, + + deleteLayers: { + value: function(arrElements) { + var i = 0, + j = 0, + arrLayersLength = this.arrLayers.length, + arrElementsLength = arrElements.length; + + for (i = 0; i < arrElementsLength; i++) { + var currentTest = arrElements[i]; + for (j = 0; j < arrLayersLength; j++) { + if (this.arrLayers[j].layerData.stageElement == currentTest) { + this.arrLayers.splice(j, 1); + } + } + } + this.selectLayers([]); + this.resetMasterDuration(); + } + }, resetMasterDuration:{ value:function(){ @@ -1274,36 +1505,37 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { handleElementAdded:{ value:function() { - this.createNewLayer(this.application.ninja.selectedElements[0]); - + this.createstageElement(this.application.ninja.selectedElements[0]); +/* if (typeof(this.currentLayerSelected) === "undefined") { // Edge case: currentLayerSelected needs to be initialized. this.currentLayerSelected = {};