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') 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