From 8ef667315ca6a81bb1369943eaf3643ae2db5037 Mon Sep 17 00:00:00 2001 From: Jon Reid Date: Mon, 26 Mar 2012 17:04:28 -0700 Subject: Timeline: Drag and Drop of layers. --- .../Timeline/TimelinePanel.reel/TimelinePanel.html | 2 +- .../Timeline/TimelinePanel.reel/TimelinePanel.js | 152 +++++++++++++++++++++ .../TimelinePanel.reel/css/TimelinePanel.css | 3 + 3 files changed, 156 insertions(+), 1 deletion(-) (limited to 'js/panels/Timeline/TimelinePanel.reel') diff --git a/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.html b/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.html index 2e0bf7dd..3833a891 100644 --- a/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.html +++ b/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.html @@ -162,7 +162,7 @@
Master Layer
-
+
diff --git a/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js b/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js index bc474a46..ffcd6686 100644 --- a/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js +++ b/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js @@ -238,6 +238,57 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { timeMarkerHolder:{ value:null }, + _dragAndDropHelper : { + value: false + }, + _dragAndDropHelperCoords: { + value: false + }, + _dragAndDropHelperOffset : { + value: false + }, + _dragLayerID : { + value: null + }, + dragLayerID : { + get: function() { + return this._dragLayerID; + }, + set: function(newVal) { + if (newVal !== this._dragLayerID) { + this._dragLayerID = newVal; + } + } + }, + _dropLayerID : { + value: null + }, + dropLayerID : { + get: function() { + return this._dropLayerID; + }, + set: function(newVal) { + if (newVal !== this._dropLayerID) { + this._dropLayerID = newVal; + + // Create a snapshot of arrLayers so we can manipulate it safely + var arrLayers = this.arrLayers, + dragLayerIndex = this.getLayerIndexByID(this.dragLayerID), + dropLayerIndex = this.getLayerIndexByID(this.dropLayerID), + dragLayer = arrLayers[dragLayerIndex]; + + arrLayers.splice(dragLayerIndex, 1); + arrLayers.splice(dropLayerIndex, 0, dragLayer); + + // Update the repetition! + this.arrLayers = arrLayers; + + // Clear for future DnD + this._dropLayerID = null; + this._dragLayerID = null; + } + } + }, /* === END: Models === */ /* === BEGIN: Draw cycle === */ prepareForDraw:{ @@ -247,6 +298,12 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { 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); + + // 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); } }, @@ -258,6 +315,25 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { } } }, + + draw: { + value: function() { + + // Drag and Drop: + // Do we have a helper to append? + if (this._appendHelper === true) { + this.container_layers.appendChild(this._dragAndDropHelper); + this._appendHelper = false; + } + // Do we need to move the helper? + if (this._dragAndDropHelperCoords !== false) { + if (this._dragAndDropHelper !== null) { + this._dragAndDropHelper.style.top = this._dragAndDropHelperCoords; + } + this._dragAndDropHelperCoords = false; + } + } + }, /* === END: Draw cycle === */ /* === BEGIN: Controllers === */ // Create an empty layer template object with minimal defaults and return it for use @@ -365,6 +441,7 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { this.layout_tracks = this.element.querySelector(".layout-tracks"); this.layout_markers = this.element.querySelector(".layout_markers"); this.timeline_leftpane.addEventListener("mousedown", this.timelineLeftPaneMousedown.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); @@ -586,6 +663,13 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { var myIndex = this.getActiveLayerIndex(); this.selectLayer(myIndex, true); } + this._isMousedown = true; + } + }, + + timelineLeftPaneMouseup:{ + value:function (event) { + this._isMousedown = false; } }, @@ -891,6 +975,74 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { } } }, + + handleLayerDragStart : { + value: function(event) { + var dragIcon = document.createElement("img"); + event.dataTransfer.effectAllowed = 'move'; + event.dataTransfer.setData('Text', this.identifier); + dragIcon.src = "/images/transparent.png"; + dragIcon.width = 1; + event.dataTransfer.setDragImage(dragIcon, 0, 0); + + // Clone the element we're dragging + this._dragAndDropHelper = event.target.cloneNode(true); + this._dragAndDropHelper.style.opacity = 0.8; + this._dragAndDropHelper.style.position = "absolute"; + this._dragAndDropHelper.style.top = "0px"; + this._dragAndDropHelper.style.left = "0px"; + this._dragAndDropHelper.style.zIndex = 700; + + this._dragAndDropHelper.style.width = window.getComputedStyle(this.container_layers, null).getPropertyValue("width"); + this._dragAndDropHelper.classList.add("timeline-dnd-helper"); + + // Get the offset + var findYOffset = function(obj) { + var curleft = curtop = 0; + if (obj.offsetParent) { + do { + curleft += obj.offsetLeft; + curtop += obj.offsetTop; + + } while (obj = obj.offsetParent); + } + return curtop; + } + this._dragAndDropHelperOffset = findYOffset(this.container_layers); + this._appendHelper = true; + // this.container_layers.appendChild(this._dragAndDropHelper); + } + }, + handleLayerDragover: { + value: function(event) { + var currPos = 0; + currPos = event.y - this._dragAndDropHelperOffset -28; + this._dragAndDropHelperCoords = currPos + "px"; + this.needsDraw = true; + } + }, + handleLayerDragEnd : { + value: function(event) { + // Delete the helper and clean up + if (this._dragAndDropHelper !== null) { + this.container_layers.removeChild(this._dragAndDropHelper); + this._dragAndDropHelper = null; + } + } + }, + handleLayerDrop : { + value: function(event) { + event.stopPropagation(); + event.preventDefault(); + // Usually drop fires after dragend, but sometimes + // dragend doesn't fire. So if we're here in drop + // and there's still a helper, we need to manually fire dragend. + if (this._dragAndDropHelper !== null) { + this.container_layers.removeChild(this._dragAndDropHelper); + this._dragAndDropHelper = null; + } + } + }, /* === END: Controllers === */ /* === BEGIN: Logging routines === */ diff --git a/js/panels/Timeline/TimelinePanel.reel/css/TimelinePanel.css b/js/panels/Timeline/TimelinePanel.reel/css/TimelinePanel.css index 129b9771..b9d45979 100644 --- a/js/panels/Timeline/TimelinePanel.reel/css/TimelinePanel.css +++ b/js/panels/Timeline/TimelinePanel.reel/css/TimelinePanel.css @@ -284,3 +284,6 @@ display: none; box-shadow: rgb(17, 17, 17) 0px 0px 14px inset; } +.timeline-dnd-helper { + -webkit-transform: scale(.9, .9); +} -- cgit v1.2.3