From c48eeb01bd726895dc577d8b843b2a75883eee07 Mon Sep 17 00:00:00 2001 From: Ananya Sen Date: Fri, 10 Feb 2012 16:03:52 -0800 Subject: Merge from /joseeight/ninja-internal/tree/FileIO Signed-off-by: Ananya Sen --- js/panels/CSSPanel/CSSPanel.js | 6 +- js/panels/Resizer.js | 4 +- js/panels/Timeline/Collapser.js | 320 ++++++ js/panels/Timeline/Keyframe.reel/Keyframe.html | 27 + js/panels/Timeline/Keyframe.reel/Keyframe.js | 154 +++ js/panels/Timeline/Keyframe.reel/css/Keyframe.css | 15 + js/panels/Timeline/Layer.reel/Layer.html | 168 ++++ js/panels/Timeline/Layer.reel/Layer.js | 626 ++++++++++++ js/panels/Timeline/Layer.reel/css/Layer.css | 322 ++++++ js/panels/Timeline/Layer.reel/images/eye.png | Bin 0 -> 1331 bytes .../Timeline/Layer.reel/images/icon-collapsed.png | Bin 0 -> 325 bytes js/panels/Timeline/Layer.reel/images/icon-eye.png | Bin 0 -> 550 bytes js/panels/Timeline/Layer.reel/images/icon-lock.png | Bin 0 -> 475 bytes .../Timeline/Layer.reel/images/icon-minus.png | Bin 0 -> 161 bytes js/panels/Timeline/Layer.reel/images/icon-open.png | Bin 0 -> 323 bytes js/panels/Timeline/Layer.reel/images/icon-plus.png | Bin 0 -> 230 bytes .../Timeline/Layer.reel/images/lock_closed.png | Bin 0 -> 1208 bytes js/panels/Timeline/Layer.reel/images/lock_open.png | Bin 0 -> 1186 bytes .../Layer.reel/images/panelDisclosureIcon.png | Bin 0 -> 3028 bytes js/panels/Timeline/Layer.reel/scss/Layer.scss | 220 +++++ js/panels/Timeline/Layer.reel/scss/config.rb | 9 + js/panels/Timeline/Span.reel/Span.html | 27 + js/panels/Timeline/Span.reel/Span.js | 41 + js/panels/Timeline/Span.reel/css/Span.css | 11 + js/panels/Timeline/Style.reel/Style.html | 91 ++ js/panels/Timeline/Style.reel/Style.js | 648 ++++++++++++ js/panels/Timeline/Style.reel/css/Style.css | 133 +++ js/panels/Timeline/Style.reel/scss/Style.scss | 70 ++ js/panels/Timeline/Style.reel/scss/config.rb | 9 + js/panels/Timeline/TimelineController.js | 13 - .../Timeline/TimelinePanel.reel/TimelinePanel.css | 6 - .../Timeline/TimelinePanel.reel/TimelinePanel.html | 242 ++++- .../Timeline/TimelinePanel.reel/TimelinePanel.js | 1027 ++++++++++++++++---- .../TimelinePanel.reel/css/TimelinePanel.css | 251 +++++ .../Timeline/TimelinePanel.reel/images/pause.png | Bin 0 -> 1076 bytes .../Timeline/TimelinePanel.reel/images/play.png | Bin 0 -> 1190 bytes .../TimelinePanel.reel/images/play_next.png | Bin 0 -> 1185 bytes .../TimelinePanel.reel/images/play_prev.png | Bin 0 -> 1199 bytes .../Timeline/TimelinePanel.reel/images/plus.png | Bin 0 -> 1133 bytes .../TimelinePanel.reel/images/timetick.jpg | Bin 0 -> 737 bytes .../Timeline/TimelinePanel.reel/images/trash.png | Bin 0 -> 1154 bytes .../Timeline/TimelineTrack.reel/TimelineTrack.html | 112 +++ .../Timeline/TimelineTrack.reel/TimelineTrack.js | 433 +++++++++ .../TimelineTrack.reel/css/TimelineTrack.css | 117 +++ .../TimelineTrack.reel/images/gridline.jpg | Bin 0 -> 724 bytes .../TimelineTrack.reel/scss/TimelineTrack.scss | 65 ++ .../Timeline/TimelineTrack.reel/scss/config.rb | 9 + js/panels/Timeline/Track.reel/Track.html | 61 ++ js/panels/Timeline/Track.reel/Track.js | 186 ++++ js/panels/Timeline/Track.reel/css/Track.css | 26 + js/panels/Timeline/Track.reel/images/gridline.jpg | Bin 0 -> 724 bytes .../Timeline/TrackSpacer.reel/TrackSpacer.html | 26 + js/panels/Timeline/TrackSpacer.reel/TrackSpacer.js | 15 + .../Timeline/TrackSpacer.reel/css/TrackSpacer.css | 5 + js/panels/Timeline/Tween.reel/Tween.html | 48 + js/panels/Timeline/Tween.reel/Tween.js | 109 +++ js/panels/Timeline/Tween.reel/css/Tween.css | 4 + 57 files changed, 5398 insertions(+), 258 deletions(-) create mode 100644 js/panels/Timeline/Collapser.js create mode 100644 js/panels/Timeline/Keyframe.reel/Keyframe.html create mode 100644 js/panels/Timeline/Keyframe.reel/Keyframe.js create mode 100644 js/panels/Timeline/Keyframe.reel/css/Keyframe.css create mode 100644 js/panels/Timeline/Layer.reel/Layer.html create mode 100644 js/panels/Timeline/Layer.reel/Layer.js create mode 100644 js/panels/Timeline/Layer.reel/css/Layer.css create mode 100644 js/panels/Timeline/Layer.reel/images/eye.png create mode 100644 js/panels/Timeline/Layer.reel/images/icon-collapsed.png create mode 100644 js/panels/Timeline/Layer.reel/images/icon-eye.png create mode 100644 js/panels/Timeline/Layer.reel/images/icon-lock.png create mode 100644 js/panels/Timeline/Layer.reel/images/icon-minus.png create mode 100644 js/panels/Timeline/Layer.reel/images/icon-open.png create mode 100644 js/panels/Timeline/Layer.reel/images/icon-plus.png create mode 100644 js/panels/Timeline/Layer.reel/images/lock_closed.png create mode 100644 js/panels/Timeline/Layer.reel/images/lock_open.png create mode 100644 js/panels/Timeline/Layer.reel/images/panelDisclosureIcon.png create mode 100644 js/panels/Timeline/Layer.reel/scss/Layer.scss create mode 100644 js/panels/Timeline/Layer.reel/scss/config.rb create mode 100644 js/panels/Timeline/Span.reel/Span.html create mode 100644 js/panels/Timeline/Span.reel/Span.js create mode 100644 js/panels/Timeline/Span.reel/css/Span.css create mode 100644 js/panels/Timeline/Style.reel/Style.html create mode 100644 js/panels/Timeline/Style.reel/Style.js create mode 100644 js/panels/Timeline/Style.reel/css/Style.css create mode 100644 js/panels/Timeline/Style.reel/scss/Style.scss create mode 100644 js/panels/Timeline/Style.reel/scss/config.rb delete mode 100755 js/panels/Timeline/TimelineController.js delete mode 100755 js/panels/Timeline/TimelinePanel.reel/TimelinePanel.css create mode 100644 js/panels/Timeline/TimelinePanel.reel/css/TimelinePanel.css create mode 100644 js/panels/Timeline/TimelinePanel.reel/images/pause.png create mode 100644 js/panels/Timeline/TimelinePanel.reel/images/play.png create mode 100644 js/panels/Timeline/TimelinePanel.reel/images/play_next.png create mode 100644 js/panels/Timeline/TimelinePanel.reel/images/play_prev.png create mode 100644 js/panels/Timeline/TimelinePanel.reel/images/plus.png create mode 100644 js/panels/Timeline/TimelinePanel.reel/images/timetick.jpg create mode 100644 js/panels/Timeline/TimelinePanel.reel/images/trash.png create mode 100644 js/panels/Timeline/TimelineTrack.reel/TimelineTrack.html create mode 100644 js/panels/Timeline/TimelineTrack.reel/TimelineTrack.js create mode 100644 js/panels/Timeline/TimelineTrack.reel/css/TimelineTrack.css create mode 100644 js/panels/Timeline/TimelineTrack.reel/images/gridline.jpg create mode 100644 js/panels/Timeline/TimelineTrack.reel/scss/TimelineTrack.scss create mode 100644 js/panels/Timeline/TimelineTrack.reel/scss/config.rb create mode 100644 js/panels/Timeline/Track.reel/Track.html create mode 100644 js/panels/Timeline/Track.reel/Track.js create mode 100644 js/panels/Timeline/Track.reel/css/Track.css create mode 100644 js/panels/Timeline/Track.reel/images/gridline.jpg create mode 100644 js/panels/Timeline/TrackSpacer.reel/TrackSpacer.html create mode 100644 js/panels/Timeline/TrackSpacer.reel/TrackSpacer.js create mode 100644 js/panels/Timeline/TrackSpacer.reel/css/TrackSpacer.css create mode 100644 js/panels/Timeline/Tween.reel/Tween.html create mode 100644 js/panels/Timeline/Tween.reel/Tween.js create mode 100644 js/panels/Timeline/Tween.reel/css/Tween.css (limited to 'js/panels') diff --git a/js/panels/CSSPanel/CSSPanel.js b/js/panels/CSSPanel/CSSPanel.js index 94860b30..cf8880a3 100755 --- a/js/panels/CSSPanel/CSSPanel.js +++ b/js/panels/CSSPanel/CSSPanel.js @@ -20,9 +20,9 @@ exports.CSSPanel = Montage.create(PanelBase, { init : { enumerable:true, value : function (){ - this.minHeight = 300; - this.contentHeight = 300; - this.defaultHeight= 300; + this.minHeight = 195; + this.contentHeight = 195; + this.defaultHeight= 195; /* OLD WAY -- Removing the temporary div // TODO: Remove this comment once this is tested. diff --git a/js/panels/Resizer.js b/js/panels/Resizer.js index 69efd6ac..3afe5d5b 100755 --- a/js/panels/Resizer.js +++ b/js/panels/Resizer.js @@ -92,7 +92,7 @@ exports.Resizer = Montage.create(Component, { handleDblclick: { value : function() { - this.panel.addEventListener("webkitTransitionEnd", this, true); + this.panel.addEventListener("webkitTransitionEnd", this, false); if (this.isVertical) { this.panel.style.height = ""; } else { @@ -102,7 +102,7 @@ exports.Resizer = Montage.create(Component, { } }, - captureWebkitTransitionEnd: { + handleWebkitTransitionEnd: { value: function() { if(this.redrawStage) { this.application.ninja.stage.resizeCanvases = true; diff --git a/js/panels/Timeline/Collapser.js b/js/panels/Timeline/Collapser.js new file mode 100644 index 00000000..d286d84c --- /dev/null +++ b/js/panels/Timeline/Collapser.js @@ -0,0 +1,320 @@ +/* + * Collapser: Takes two elements and creates a visual "expando:" clicking on one element expands/collapses the other. + * Required properties: + * clicker: The element that will be clicked on. + * content: The element that will expand or collapse as the clicker is clicked on. + * Optional properties: + * isCollapsed: Is the content collapsed. Set to true on serialization (or initialization) to start content in collapsed state. + * Can be manually set as well. + * collapsibleClass: The CSS class to apply to the content and the clicker when collapsed. Defaults to "collapsible-collapsed". + * isAnimated: Set to true to apply a transition to expand/collapse (defaults to false). + * transitionClass: If isAnimated is set to true, the component will apply transitionClass to the content during the + * collapse process. You can then define transitionClass in your style sheet with the desired CSS transitions. + * Defaults to "collapsible-transition". + * contentHeight: If both isAnimated and isCollapsedAtStart are set to true, set contentHeight to the height of the content + * (in pixels, but without the "px") when not collapsed. If this value is not set, the first time the content is expanded + * the transition will not work. Subsequent collapses (and expansions) will transition as expected. + * isLabelClickable: Boolean that indicates whether or not the clicker should have listener events. Defaults to true; set to + * false for collapsers that will only be operated remotely. + * toggle(): Manually toggle the expand/collapse of the content. + * + */ +var Montage = require("montage/core/core").Montage, + Component = require("montage/ui/component").Component, + Collapser = exports.Collapser = Montage.create(Component, { + + // This component has no template. + hasTemplate:{ + value: false + }, + + /* === BEGIN: Models === */ + + // contentHeight: Stores the height of the content just before collapse. + _contentHeight: { + value: 0 + }, + contentHeight: { + get: function() { + return this._contentHeight; + }, + set: function(newVal) { + this._contentHeight = newVal; + } + }, + + // isCollapsing: true if the collapser is collapsing (or expanding); used in the draw cycle. + _isCollapsing: { + value: false + }, + + // isAnimated: boolean to apply transition to expand/collapse + _isAnimated : { + value: false + }, + isAnimated: { + get: function() { + return this._isAnimated; + }, + set: function(newVal) { + this._isAnimated = newVal; + } + }, + + _bypassAnimation : { + value: false + }, + bypassAnimation: { + get: function() { + return this._bypassAnimation; + }, + set: function(newVal) { + this._bypassAnimation= newVal; + } + }, + + // transitionClass: The CSS class to apply to the content during collapse to provide CSS transition. + // Note that this CSS class must be defined in your style sheet with the desired transitions. + _transitionClass : { + value: "collapsible-transition" + }, + transitionClass: { + get: function() { + return this._transitionClass; + }, + set: function(newVal) { + this._transitionClass = newVal; + } + }, + + // isCollapsed: is the content actually collapsed at this moment + _isCollapsed: { + value: "" + }, + isCollapsed : { + get: function() { + return this._isCollapsed; + }, + set: function(newVal) { + if (newVal !== this._isCollapsed) { + this._isCollapsed = newVal; + this.needsDraw = true; + } + + } + }, + + // collapsedClass: the class to apply to the clicker and content when the content is collapsed. + _collapsedClass : { + value: "collapsible-collapsed" + }, + collapsedClass: { + get: function() { + return this._collapsedClass; + }, + set: function(newVal) { + this._collapsedClass = newVal; + } + }, + + // _origOverflowValue: Stores the original overflow value of the collapsible element. + // Why store the value? While the collapsible element is collapsed, obviously we will need overflow: hidden. + // But when the collapsible element is open, we will need overflow to return to its original value. + _origOverflowValue : { + value: false + }, + + // isLabelClickable: Boolean for whether or not the label is clickable. If set to false, + // the label click listener is never applied. For collapsibles that will only be operated remotely. + // Defaults to true. + _isLabelClickable : { + value: true + }, + isLabelClickable : { + get: function() { + return this._isLabelClickable; + }, + set: function(newVal) { + this._isLabelClickable = newVal; + } + }, + + // labelClickEvent: an event to fire when the label is clicked. + _labelClickEvent: { + value: false + }, + labelClickEvent: { + get: function() { + return this._labelClickEvent; + }, + set: function(newVal) { + this._labelClickEvent = newVal; + } + }, + + // toggle: manually toggle the collapser. + toggle: { + value: function() { + if (this.bypassAnimation) { + this.isAnimated = false; + } + this.myContent.classList.remove(this.transitionClass); + this.handleCollapserLabelClick(); + } + }, + + /* === END: Models === */ + + /* === BEGIN: Draw cycle === */ + + prepareForDraw: { + value: function() { + // Add a click listener to the label for expand/collapse + if (this.isLabelClickable) { + this.clicker.identifier = "collapserLabel"; + this.clicker.addEventListener("click", this, false); + } + + // Get the original value of the overflow property: + this._origOverflowValue = window.getComputedStyle(this.myContent, null).getPropertyValue("overflow"); + + // If the content area is supposed to start out collapsed: + if (this.isCollapsed) { + this.myContent.style.height = "0px"; + // Set the overflow to hidden if it's not already + if (this._origOverflowValue !== "hidden") { + this.myContent.style.overflow = "hidden"; + } + this.myContent.classList.add(this.collapsedClass); + this.clicker.classList.add(this.collapsedClass); + } else { + this.myContent.style.height = "auto"; + this.myContent.classList.remove(this.collapsedClass); + this.clicker.classList.remove(this.collapsedClass); + } + } + }, + draw: { + value: function() { + // Is the content area expanding/collapsing? + this.myContent.classList.remove(this.transitionClass); + if (this._isCollapsing) { + + if (this.isAnimated) { + // Apply the transition class to the content. + this.myContent.classList.add(this.transitionClass); + + // Add a handler for the end of the transition, so we can tidy things up after + // the transition completes + this.myContent.identifier = "myContent"; + this.myContent.addEventListener("webkitTransitionEnd", this, false); + + this.myContent.style.overflow = "hidden"; + } + + // Next, are we expanding or collapsing? + if (this.myContent.classList.contains(this.collapsedClass)) { + // It's already collapsed so we are expanding + this.myContent.style.height = this.contentHeight + "px"; + this.isCollapsed = false; + + } else { + // It's expanded so we are collapsing + this.myContent.style.height = "0px"; + this.isCollapsed = true; + + // Set the overflow to hidden if it isn't already + if (this._origOverflowValue !== "hidden") { + this.myContent.style.overflow = "hidden"; + } + } + + // Toggle the CSS class and deactivate the collapsing flag because we are now done. + this.myContent.classList.toggle(this.collapsedClass); + this.clicker.classList.toggle(this.collapsedClass); + this._isCollapsing = false; + + // Special cases: If transition does not happen (in the case of a contentHeight of 0 + // or isAnimated = false) we need to manually fire it here to do the cleanup. + if ((this.contentHeight < 3) || (!this.isAnimated)) { + this.handleMyContentWebkitTransitionEnd(); + } + } + } + }, + + /* === END: Draw cycle === */ + + /* === BEGIN: Event handlers === */ + + // Handle a click on the label + handleCollapserLabelClick: { + value: function() { + + // The user has clicked on one of the expandos. What should we do? + // First, are we expanding or collapsing? + if (!this.myContent.classList.contains(this.collapsedClass)) { + // We are collapsing! + // Save the current height of the content. + this.contentHeight = this.myContent.offsetHeight; + // Set the current height of the content to a pixel height instead of "auto" + // so that the transition can happen. + // (This doesn't actually change the appearance of the element, + // so it's okay to do here, outside the draw cycle.) + this.myContent.style.height = this.contentHeight + "px"; + + this.isCollapsed = true; + } else { + this.isCollapsed = false; + } + + // Set the collapsing flag so when the draw cycle begins + // it will know to expand/collapse. + this._isCollapsing = true; + + // Set the component to run its draw cycle. + this.needsDraw = true; + + // Dispatch my labelClick event + if (this.labelClickEvent) { + this.labelClickEvent(this.bypassAnimation); + } + + } + }, + + // This handler is bound to the transitionEnd event. If transitions + // are disabled, it is called manually. + handleMyContentWebkitTransitionEnd: { + value: function(event) { + + // Are we animating the transitions? + if (this.isAnimated) { + // Yes, transitions are animated. + // Remove the event listener so it won't fire again. + this.myContent.removeEventListener("webkitTransitionEnd", this, false); + + // remove the CSS class that supplies the transition + this.myContent.classList.remove(this.transitionClass); + } + + // Set the height of the content area to auto; this way it can expand/collapse as interactions + // happen within. + if (!this.myContent.classList.contains(this.collapsedClass)) { + this.myContent.style.height = "auto"; + // Return the overflow to its original value if it wasn't hidden + if (this._origOverflowValue !== "hidden") { + this.myContent.style.overflow = this._origOverflowValue; + } + + } + + if (this.bypassAnimation) { + this.bypassAnimation = false; + this.isAnimated = true; + } + } + } + + /* === END: Event handlers === */ +}); \ No newline at end of file diff --git a/js/panels/Timeline/Keyframe.reel/Keyframe.html b/js/panels/Timeline/Keyframe.reel/Keyframe.html new file mode 100644 index 00000000..bf21994b --- /dev/null +++ b/js/panels/Timeline/Keyframe.reel/Keyframe.html @@ -0,0 +1,27 @@ + + + + + + + + + +
+
+
+ + + \ No newline at end of file diff --git a/js/panels/Timeline/Keyframe.reel/Keyframe.js b/js/panels/Timeline/Keyframe.reel/Keyframe.js new file mode 100644 index 00000000..c82a9086 --- /dev/null +++ b/js/panels/Timeline/Keyframe.reel/Keyframe.js @@ -0,0 +1,154 @@ +var Montage = require("montage/core/core").Montage; +var Component = require("montage/ui/component").Component; +var ElementsMediator = require("js/mediators/element-mediator").ElementMediator; + +var Keyframe = exports.Keyframe = Montage.create(Component, { + + hasTemplate:{ + value: true + }, + + _position:{ + value:0 + }, + + position:{ + serializable:true, + get:function(){ + return this._position; + }, + set:function(value){ + this._position = value; + } + }, + + _id:{ + value:0 + }, + + id:{ + serializable:true, + get:function () { + return this._id; + }, + set:function (value) { + this._id = value; + } + }, + + _timelinePosition:{ + value:0 + }, + + timelinePosition:{ + serializable:true, + get:function () { + return this._timelinePosition; + }, + set:function (value) { + this._timelinePosition = value; + } + }, + + _containingTrack:{ + value:{} + }, + + containingTrack:{ + serializable:true, + get:function () { + return this._containingTrack; + }, + set:function (value) { + this._containingTrack = value; + } + }, + + _animatedProperties:{ + value:[] + }, + + animatedProperties:{ + serializable:true, + get:function () { + return this._animatedProperties; + }, + set:function (value) { + this._animatedProperties = value; + } + }, + + containingSpan:{ + value: null + }, + + prepareForDraw:{ + value:function(){ + this.tweenkeyframe.addEventListener("click", this, false); + this.animatedProperties = new Array(); + this.animatedProperties["top"] = this.containingTrack.animatedElement.offsetTop; + this.animatedProperties["left"] = this.containingTrack.animatedElement.offsetLeft; + } + }, + + draw:{ + value:function(){ + this.tweenkeyframe.style.left = (this.position - 3) + "px"; + } + }, + + handleElementChange:{ + value:function (event) { + if(this.application.ninja.selectedElements[0]._element != this.containingTrack.animatedElement){ + alert("Wrong element selected for this keyframe track"); + return; + } + + if(event.detail.source && event.detail.source !== "keyframe") { + this.containingSpan.highlightSpan(); + if(this.containingTrack.animatedElement.offsetTop != this.animatedProperties["top"] && this.containingTrack.animatedElement.offsetLeft != this.animatedProperties["left"]){ + this.animatedProperties["top"] = this.containingTrack.animatedElement.offsetTop; + this.animatedProperties["left"] = this.containingTrack.animatedElement.offsetLeft; + this.containingTrack.keyFramePropertyData[this.id] = this.animatedProperties; + this.containingTrack.updateKeyframeRule(); + } + } + } + }, + + deselect:{ + value:function(){ + this.tweenkeyframe.classList.remove("keyframeSelected"); + this.eventManager.removeEventListener("elementChange", this, false); + } + }, + + select:{ + value:function(){ + this.application.ninja.timeline.deselectKeyframes(); + this.tweenkeyframe.classList.add("keyframeSelected"); + this.application.ninja.timeline.playhead.style.left = (this.timelinePosition - 2) + "px"; + this.application.ninja.timeline.playheadmarker.style.left = this.timelinePosition + "px"; + this.application.ninja.timeline.selectedKeyframes.push(this); + + var currentMillisecPerPixel = Math.floor(this.application.ninja.timeline.millisecondsOffset / 80); + var currentMillisec = currentMillisecPerPixel * this.timelinePosition; + this.application.ninja.timeline.updateTimeText(currentMillisec); + + var currentTop = this.animatedProperties["top"] + "px"; + var currentLeft = this.animatedProperties["left"] + "px"; + + ElementsMediator.setProperty([this.containingTrack.animatedElement], "top", [currentTop], "Change", "keyframe"); + ElementsMediator.setProperty([this.containingTrack.animatedElement], "left", [currentLeft], "Change", "keyframe"); + + // turn on element change event listener + this.eventManager.addEventListener("elementChange", this, false); + } + }, + + handleClick:{ + value:function(ev){ + this.select(); + } + } +}); diff --git a/js/panels/Timeline/Keyframe.reel/css/Keyframe.css b/js/panels/Timeline/Keyframe.reel/css/Keyframe.css new file mode 100644 index 00000000..4afc1180 --- /dev/null +++ b/js/panels/Timeline/Keyframe.reel/css/Keyframe.css @@ -0,0 +1,15 @@ +.tween_keyframe{ + position: absolute; + height: 16px; + width: 5px; + background-color: white; + z-index: 23; + border-radius: 3px; +} + +.tween_keyframe.keyframeSelected{ + background-color: #570e19; + border-style: solid; + border-width: thin; + border-color: #d6d1cf; +} \ No newline at end of file diff --git a/js/panels/Timeline/Layer.reel/Layer.html b/js/panels/Timeline/Layer.reel/Layer.html new file mode 100644 index 00000000..dd819b2b --- /dev/null +++ b/js/panels/Timeline/Layer.reel/Layer.html @@ -0,0 +1,168 @@ + + + + + + + + + +
+
+ Label + +
+
+
+
+
+ Position + +
+
+
+
+
X
+
100px
+
+
+
Y
+
100px
+
+
+
Z
+
100px
+
+
+
+
+ Transform + +
+
+
+
+
Scale X
+
100px
+
+
+
Scale Y
+
100px
+
+
+
Skew X
+
100px
+
+
+
Skew Y
+
100px
+
+
+
Rotation
+
100px
+
+
+ +
+
+ Style + +
+
+
+
+
+
+
+
+
+
+
+ + \ No newline at end of file diff --git a/js/panels/Timeline/Layer.reel/Layer.js b/js/panels/Timeline/Layer.reel/Layer.js new file mode 100644 index 00000000..71a1f01f --- /dev/null +++ b/js/panels/Timeline/Layer.reel/Layer.js @@ -0,0 +1,626 @@ +var Montage = require("montage/core/core").Montage; +var Component = require("montage/ui/component").Component; +var Collapser = require("js/panels/Timeline/Collapser").Collapser; +var Hintable = require("js/components/hintable.reel").Hintable; +var LayerStyle = require("js/panels/Timeline/Style.reel").LayerStyle; +var DynamicText = require("montage/ui/dynamic-text.reel").DynamicText; +var defaultEventManager = require("montage/core/event/event-manager").defaultEventManager; +var nj = require("js/lib/NJUtils").NJUtils; + +var Layer = exports.Layer = Montage.create(Component, { + + hasTemplate:{ + value: true + }, + + /* Begin: Models */ + + /* Main collapser model: the main collapser for the layer */ + _mainCollapser : { + value: false + }, + mainCollapser: { + get: function() { + return this._mainCollapser; + }, + set: function(newVal) { + this._mainCollapser = newVal; + } + }, + + /* Style models: the array of styles, and the repetition that uses them */ + _arrLayerStyles : { + serializable: true, + enumerable: true, + serializable: true, + value: [] + }, + arrLayerStyles : { + serializable: true, + enumerable: true, + serializable: true, + get: function() { + return this._arrLayerStyles; + }, + set: function(newVal) { + this._arrLayerStyles = newVal; + } + }, + _styleRepetition : { + value: false + }, + styleRepetition : { + get: function() { + return this._styleRepetition; + }, + set: function(newVal) { + this._styleRepetition = newVal; + } + }, + _styleCounter : { + value: 0 + }, + + /* Layer models: the name, ID, and selected and animation booleans for the layer */ + _layerName:{ + serializable: true, + value:null, + writable:true, + enumerable:true + }, + + layerName:{ + serializable: true, + get:function(){ + return this._layerName; + }, + set:function(newVal){ + if (newVal !== this._layerName) { + this._layerEditable.value = newVal; + this._layerName = newVal; + this._layerEditable.needsDraw = true; + this.needsDraw = true; + + } + + } + }, + _layerID:{ + value:null, + writable:true, + serializable: true, + enumerable:true + }, + + layerID:{ + serializable: true, + get:function(){ + return this._layerID; + }, + set:function(value){ + this._layerID = value; + } + }, + + /* isSelected: whether or not the layer is currently selected. */ + _isSelected:{ + value: false, + writable: true, + serializable: true, + enumerable: false + }, + + isSelected:{ + get:function(){ + return this._isSelected; + }, + set:function(value){ + if (value !== this._isSelected) { + // Only concerned about different values + if (value === false) { + // If changing from false to true, we need to deselect any associated styles + this.selectStyle(false); + } + this._isSelected = value; + this.needsDraw = true; + } + + } + }, + + /* isActive: Whether or not the user is actively clicking within the layer; used to communicate state with + * TimelinePanel. + */ + _isActive: { + value: false + }, + isActive: { + get: function() { + return this._isActive; + }, + set: function(newVal) { + this._isActive = newVal; + } + }, + + + _isAnimated:{ + value: false, + writable: true, + enumerable: false + }, + + isAnimated:{ + get:function(){ + return this._isAnimated; + }, + set:function(value){ + this._isAnimated = value; + } + }, + _justAdded: { + value: false + }, + _layerEditable : { + value: false + }, + + // Are the various collapsers collapsed or not + _isMainCollapsed : { + value: "" + }, + isMainCollapsed : { + get: function() { + return this._isMainCollapsed; + }, + set: function(newVal) { + if (newVal !== this._isMainCollapsed) { + this._isMainCollapsed = newVal; + this.needsDraw = true; + } + } + }, + + _isTransformCollapsed : { + value: true + }, + isTransformCollapsed : { + get: function() { + return this._isTransformCollapsed; + }, + set: function(newVal) { + if (newVal !== this._isTransformCollapsed) { + this._isTransformCollapsed = newVal; + this.needsDraw = true; + } + } + }, + + _isPositionCollapsed : { + value: true + }, + isPositionCollapsed : { + get: function() { + return this._isPositionCollapsed; + }, + set: function(newVal) { + if (newVal !== this._isPositionCollapsed) { + this._isPositionCollapsed = newVal; + this.needsDraw = true; + } + } + }, + + _isStyleCollapsed : { + value: true + }, + isStyleCollapsed : { + get: function() { + return this._isStyleCollapsed; + }, + set: function(newVal) { + if (newVal !== this._isStyleCollapsed) { + this._isStyleCollapsed = newVal; + this.needsDraw = true; + } + } + }, + + + /* END: Models */ + + /* Begin: Draw cycle */ + prepareForDraw: { + value: function() { + + // Initialize myself + this.init(); + + var that = this; + + this.positionCollapser = Collapser.create(); + this.transformCollapser = Collapser.create(); + this.styleCollapser = Collapser.create(); + + // Make it editable! + this._layerEditable = Hintable.create(); + this._layerEditable.element = this.titleSelector; + this.titleSelector.identifier = "selectorEditable"; + this.titleSelector.addEventListener("click", this, false); + this._layerEditable.addEventListener("blur", function(event) { + that.handleSelectorEditableBlur(event); + }, false); + this._layerEditable.addEventListener("change", function(event) { + that.dynamicLayerName.value = that._layerEditable.value; + that.needsDraw = true; + }, false); + this._layerEditable.editingClass = "editable2"; + this._layerEditable.value = this.layerName; + this._layerEditable.needsDraw = true; + + // Change the markup into collapsible sections using the nifty Collapser component! + this.mainCollapser = Collapser.create(); + this.mainCollapser.clicker = this.clicker; + this.mainCollapser.myContent = this.myContent; + this.mainCollapser.contentHeight = 60; + this.myContent.style.height = "0px"; + this.mainCollapser.element = this.element; + //this.mainCollapser.isCollapsedAtStart = true; + this.mainCollapser.isCollapsed = this.isMainCollapsed; + this.mainCollapser.isAnimated = true; + this.element.setAttribute("data-layerid", this.layerID); + this.mainCollapser.labelClickEvent = function(boolBypass) { + var newEvent = document.createEvent("CustomEvent"); + newEvent.initCustomEvent("layerEvent", false, true); + newEvent.layerEventLocale = "content-main"; + newEvent.layerEventType = "labelClick"; + newEvent.layerID = that.layerID; + newEvent.bypassAnimation = boolBypass; + defaultEventManager.dispatchEvent(newEvent); + that.isMainCollapsed = that.mainCollapser.isCollapsed; + } + this.mainCollapser.needsDraw = true; + + this.positionCollapser.clicker = this.clickerPosition; + this.positionCollapser.myContent = this.contentPosition; + this.positionCollapser.element = this.element; + this.positionCollapser.contentHeight = 60; + // this.positionCollapser.isCollapsedAtStart = true; + this.positionCollapser.isCollapsed = this.isPositionCollapsed; + this.positionCollapser.isAnimated = true; + this.positionCollapser.labelClickEvent = function(boolBypass) { + var newEvent = document.createEvent("CustomEvent"); + newEvent.initCustomEvent("layerEvent", false, true); + newEvent.layerEventLocale = "content-position"; + newEvent.layerEventType = "labelClick"; + newEvent.layerID = that.layerID; + newEvent.bypassAnimation = boolBypass; + defaultEventManager.dispatchEvent(newEvent); + that.isPositionCollapsed = that.positionCollapser.isCollapsed; + } + this.positionCollapser.needsDraw = true; + + this.transformCollapser.clicker = this.clickerTransform; + this.transformCollapser.myContent = this.contentTransform; + this.transformCollapser.element = this.element; + this.transformCollapser.contentHeight = 100; + // this.transformCollapser.isCollapsedAtStart = true; + this.transformCollapser.isCollapsed = this.isTransformCollapsed; + this.transformCollapser.isAnimated = true; + this.transformCollapser.labelClickEvent = function(boolBypass) { + var newEvent = document.createEvent("CustomEvent"); + newEvent.initCustomEvent("layerEvent", false, true); + newEvent.layerEventLocale = "content-transform"; + newEvent.layerEventType = "labelClick"; + newEvent.layerID = that.layerID; + newEvent.bypassAnimation = boolBypass; + defaultEventManager.dispatchEvent(newEvent); + that.isTransformCollapsed = that.transformCollapser.isCollapsed; + } + this.transformCollapser.needsDraw = true; + + this.styleCollapser.clicker = this.clickerStyle; + this.styleCollapser.myContent = this.contentStyle; + this.styleCollapser.element = this.element; + this.styleCollapser.isCollapsed = this.isStyleCollapsed; + this.styleCollapser.isAnimated = true; + this.styleCollapser.labelClickEvent = function(boolBypass) { + var newEvent = document.createEvent("CustomEvent"); + newEvent.initCustomEvent("layerEvent", false, true); + newEvent.layerEventLocale = "content-style"; + newEvent.layerEventType = "labelClick"; + newEvent.layerID = that.layerID; + newEvent.bypassAnimation = boolBypass; + defaultEventManager.dispatchEvent(newEvent); + that.isStyleCollapsed = that.styleCollapser.isCollapsed; + } + this.styleCollapser.needsDraw = true; + + // Add event listeners to add and delete style buttons + this.buttonAddStyle.identifier = "addStyle"; + this.buttonAddStyle.addEventListener("click", this, false); + + this.buttonDeleteStyle.identifier = "deleteStyle"; + this.buttonDeleteStyle.addEventListener("click", this, false); + + // Add mousedown listener to set isActive + this.element.addEventListener("mousedown", this, false); + //this.element.addEventListener("click", this, false); + + } + }, + draw: { + value: function() { + + // Coordinate the collapsers + if (this.mainCollapser.isCollapsed !== this.isMainCollapsed) { + this.mainCollapser.bypassAnimation = true; + this.mainCollapser.toggle(); + } + if (this.positionCollapser.isCollapsed !== this.isPositionCollapsed) { + this.positionCollapser.bypassAnimation = true; + this.positionCollapser.toggle(); + } + if (this.transformCollapser.isCollapsed !== this.isTransformCollapsed) { + this.transformCollapser.bypassAnimation = true; + this.transformCollapser.toggle(); + } + if (this.styleCollapser.isCollapsed !== this.isStyleCollapsed) { + this.styleCollapser.bypassAnimation = true; + this.styleCollapser.toggle(); + } + + if (this.isSelected) { + this.element.classList.add("selected"); + } else { + this.element.classList.remove("selected"); + } + } + }, + /* End: Draw cycle */ + + /* Begin: Controllers */ + + // Initialize a just-created layer with some basic defaults and needed selectors. + init: { + value: function() { + // Default some vars + //this.arrLayerStyles = []; + + // Get some selectors. + this.label = this.element.querySelector(".label-layer"); + this.titleSelector = this.label.querySelector(".collapsible-label"); + this.clicker = this.element.querySelector(".collapsible-clicker"); + this.myContent = this.element.querySelector(".content-layer"); + this.clickerPosition = this.element.querySelector(".clicker-position"); + this.contentPosition = this.element.querySelector(".content-position"); + this.clickerTransform = this.element.querySelector(".clicker-transform"); + this.contentTransform = this.element.querySelector(".content-transform"); + this.clickerStyle = this.element.querySelector(".clicker-style"); + this.contentStyle = this.element.querySelector(".content-style"); + this.buttonAddStyle = this.element.querySelector(".button-add"); + this.buttonDeleteStyle = this.element.querySelector(".button-delete"); + } + }, + selectLayer:{ + value:function(){ + // this.mainCollapser.header.classList.add("layerSelected"); + this.element.classList.add("layerSelected"); + this.isSelected = true; + } + }, + deselectLayer:{ + value:function(){ + // this.mainCollapser.header.classList.remove("layerSelected"); + this.element.classList.remove("layerSelected"); + this.isSelected = false; + } + }, + addStyle : { + value: function() { + // Add a new style rule. It should be added above the currently selected rule, + // Or at the end, if no rule is selected. + + var newLength = 0, + mySelection = 0, + // newStyle = LayerStyle.create(), + newStyle = {}, + newEvent = document.createEvent("CustomEvent"); + + this.isStyleCollapsed = false; + + newEvent.initCustomEvent("layerEvent", false, true); + newEvent.layerEventLocale = "styles"; + newEvent.layerEventType = "newStyle"; + newEvent.layerID = this.layerID; + newEvent.styleID = this.layerID + "@" + this._styleCounter; + + newStyle.styleID = newEvent.styleID; + newStyle.whichView = "hintable"; + newStyle.editorProperty = ""; + newStyle.editorValue = ""; + newStyle.ruleTweener = false; + newStyle.isSelected = false; + + if (!!this.styleRepetition.selectedIndexes) { + mySelection = this.styleRepetition.selectedIndexes[0]; + this.arrLayerStyles.splice(mySelection, 0, newStyle); + //this.styleRepetition.selectedIndexes = [mySelection]; + this.selectStyle(mySelection); + } else { + newLength = this.arrLayerStyles.length; + this.arrLayerStyles.push(newStyle); + mySelection = this.arrLayerStyles.length; + // this.styleRepetition.selectedIndexes = [mySelection-1]; + this.selectStyle(mySelection-1); + } + + // Set up the event info and dispatch the event + + newEvent.styleSelection = mySelection; + defaultEventManager.dispatchEvent(newEvent); + + } + }, + deleteStyle : { + value: function() { + var newEvent = document.createEvent("CustomEvent"), + selectedIndex = 0; + if (this.arrLayerStyles.length > 0) { + if (!!this.styleRepetition.selectedIndexes) { + + selectedIndex = this.styleRepetition.selectedIndexes[0]; + + // Set up the event info and dispatch the event + newEvent.initCustomEvent("layerEvent", false, true); + newEvent.layerEventLocale = "styles"; + newEvent.layerEventType = "deleteStyle"; + newEvent.layerID = this.layerID; + newEvent.styleID = this.arrLayerStyles[selectedIndex].styleID; + newEvent.styleSelection = selectedIndex; + defaultEventManager.dispatchEvent(newEvent); + + // Delete the style from the view + this.arrLayerStyles.splice(selectedIndex, 1); + + } else { + alert('TODO: what should happen when no rule is selected and the user clicks the delete button?') + } + } + } + }, + selectStyle : { + value: function(styleIndex) { + + // Select a style based on its index. + // use layerIndex = false to deselect all styles. + var i = 0, + arrLayerStylesLength = this.arrLayerStyles.length; + + // First, update this.arrStyles[].isSelected + for (i = 0; i < arrLayerStylesLength; i++) { + if (i === styleIndex) { + this.arrLayerStyles[i].isSelected = true; + } else { + this.arrLayerStyles[i].isSelected = false; + } + } + + // Next, update this.styleRepetition.selectedIndexes. + if (styleIndex !== false) { + this.styleRepetition.selectedIndexes = [styleIndex]; + } else { + this.styleRepetition.selectedIndexes = null; + } + + } + }, + getActiveStyleIndex : { + value: function() { + // Searches through the styles and looks for one that has + // set its isActive flag to true. + var i = 0, + returnVal = false, + arrLayerStylesLength = this.arrLayerStyles.length; + + for (i = 0; i < arrLayerStylesLength; i++) { + if (this.arrLayerStyles[i].isActive === true) { + returnVal = i; + this.arrLayerStyles[i].isActive = false; + } + } + return returnVal; + } + }, + /* End: Controllers */ + + /* Begin: Event handlers */ + handleAddStyleClick: { + value: function(event) { + // Stop the event propagation + //event.stopPropagation(); + this.addStyle(); + } + }, + handleDeleteStyleClick: { + value: function(event) { + //event.stopPropagation(); + this.deleteStyle(); + } + }, + handleSelectorEditableClick: { + value: function(event) { + } + }, + handleSelectorEditableBlur : { + value: function(event) { + this.titleSelector.scrollLeft = 0; + } + }, + handleSelectorEditableChange: { + value: function(event) { + this.layerName = this.dynamicLayerName.value; + this.needsDraw = true; + } + }, + handleMousedown: { + value: function(event) { + this.isActive = true; + // Check ALL THE CLICKS + // Are they in a particular style? If so, we need to select that style and + // deselect the others. + var ptrParent = nj.queryParentSelector(event.target, ".content-style"); + if (ptrParent !== false) { + // Why yes, the click was within a layer. But which one? + var myIndex = this.getActiveStyleIndex(); + this.selectStyle(myIndex); + } + } + }, + handleLayerClick : { + value: function(event) { + // Check ALL THE CLICKS + // Are they in a particular style? If so, we need to select that style and + // deselect the others. + var ptrParent = nj.queryParentSelector(event.target, ".content-style"); + if (ptrParent !== false) { + // Why yes, the click was within a layer. But which one? + var myIndex = this.getActiveStyleIndex(); + this.selectStyle(myIndex); + } + } + }, + /* End: Event handlers */ + + /* Begin: Logging routines */ + _boolDebug: { + enumerable: false, + value: false // set to true to enable debugging to console; false for turning off all debugging. + }, + boolDebug: { + get: function() { + return this._boolDebug; + }, + set: function(boolDebugSwitch) { + this._boolDebug = boolDebugSwitch; + } + }, + log: { + value: function(strMessage) { + if (this.boolDebug) { + console.log(this.getLineNumber() + ": " + strMessage); + } + } + }, + getLineNumber: { + value: function() { + try { + throw new Error('bazinga') + }catch(e){ + return e.stack.split("at")[3].split(":")[2]; + } + } + } + /* End: Logging routines */ + +}); \ No newline at end of file diff --git a/js/panels/Timeline/Layer.reel/css/Layer.css b/js/panels/Timeline/Layer.reel/css/Layer.css new file mode 100644 index 00000000..39869c92 --- /dev/null +++ b/js/panels/Timeline/Layer.reel/css/Layer.css @@ -0,0 +1,322 @@ +@charset "UTF-8"; +/* Layer.scss + * Main SCSS file for Layer component, compiled by SASS into the file css/Layer.css. + */ +/* + This file contains proprietary software owned by Motorola Mobility, Inc.
+ No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.
+ (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. +
*/ +/* + * _colors.scss + * Defines the colors for the UI of the application. + * To create a new theme, copy this file and change the values as desired. + * Note: Some colors are defined as both rgb and rgba; some of the rgba versions have multiple a values. + */ +/* Colors for radio buttons and other form elements */ +/* Base colors for dividers + * + * Dividers consist of a div with a background color and either + * a top & bottom border (in the case of horizontal dividers) + * or a left & right border (in the case of vertical dividers), + * for a total of three different colors. + * + */ +/* top and left */ +/* Middle */ +/* Bottom and right */ +/* Main background color of entire app */ +/* Main app background color. */ +/* rgba version */ +/* Main app border color */ +/* color of drop shadows */ +/* Stage color */ +/* body border color */ +/* Body background color */ +/* Colors for main dropdown menus: background & text for both regular and highlighted states, dividers */ +/* Colors for tools: background, text, how they interact with the UI */ +/* Colors for panels: background & text, both regular and highlighted states, dividers, borders, shadows, etc. */ +/* used for editable items in their non-edit state, etc. */ +/* Border for panel and for block elements */ +/* Shadow for text and block elements */ +/* Colors for scroll bars */ +/* + This file contains proprietary software owned by Motorola Mobility, Inc.
+ No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.
+ (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. +
*/ +/* + * themes/themename/mixins.scss + * Mixins that are theme-dependent (e.g. sprite mixins, etc) + */ +/* + This file contains proprietary software owned by Motorola Mobility, Inc.
+ No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.
+ (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. +
*/ +/* + * mixins.scss + * Generic mixins. Theme-specific mixins (e.g. for sprites) + * should go in the theme/themename/mixins.scss file. + */ +/* line 16, ../scss/Layer.scss */ +.layerLabel { + width: 100%; + color: white; + height: 21px; + font-family: 'Droid Sans'; + font-size: 12px; + text-shadow: 1px 1px 1px #3a3a3a; + display: -webkit-box; + -webkit-box-orient: horizontal; +} + +/* line 26, ../scss/Layer.scss */ +.layerLabel.layerSelected { + background-color: #b2b2b2; + color: #242424; +} + +/* line 30, ../scss/Layer.scss */ +.layerLabel { + width: 100%; + height: 18px; + padding-left: 25px; + padding-top: 2px; + -webkit-box-flex: 1; +} + +/* line 37, ../scss/Layer.scss */ +.layerDisclosure { + background-image: url("../images/panelDisclosureIcon.png"); + background-repeat: no-repeat; + width: 16px; + height: 16px; + /*float: left;*/ + -webkit-transition-property: rotate; + -webkit-transition-duration: 0.2s; + -webkit-transition-timing-function: linear; + padding-right: 2px; + -webkit-box-flex: 0; +} + +/* line 50, ../scss/Layer.scss */ +.layerHide { + background-image: url("../images/eye.png"); + background-repeat: no-repeat; + /*float: right;*/ + width: 16px; + height: 16px; + padding-right: 4px; + -webkit-box-flex: 0; +} + +/* line 59, ../scss/Layer.scss */ +.layerLock { + background-image: url("../images/lock_open.png"); + background-repeat: no-repeat; + /*float: right;*/ + width: 16px; + height: 16px; + padding-right: 4px; + -webkit-box-flex: 0; +} + +/******************************************/ +/* line 71, ../scss/Layer.scss */ +.container-layer { + background-color: #474747; + color: white; + font-size: 12px; + text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5); +} + +/* line 77, ../scss/Layer.scss */ +.selected .container-layer { + background-color: #474747; +} + +/* line 80, ../scss/Layer.scss */ +.selected .container-layer .label-layer { + background-color: #b2b2b2; + color: #242424; +} + +/* line 85, ../scss/Layer.scss */ +.userlayers .collapsible-label { + display: block; + width: 100px; + height: 21px; + line-height: 20px; + color: white; + margin-left: 30px; + margin-right: 20px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +/* line 97, ../scss/Layer.scss */ +.layerSelected .label-layer { + background-color: #b2b2b2; + color: #242424; +} + +/* line 101, ../scss/Layer.scss */ +.content-layer { + background-color: #474747; + color: white; +} + +/* line 105, ../scss/Layer.scss */ +.content-layer .collapsible-label { + background-position: 14px 5px; + border-width: 0px; +} + +/* line 112, ../scss/Layer.scss */ +.label-layer, +.label-position, +.label-transform, +.label-style { + position: relative; + border-bottom: 1px solid #505050; + cursor: pointer; +} + +/* line 119, ../scss/Layer.scss */ +.content-layer .collapsible-label, +.content-layer .collapsible-content { + font-size: 11px; +} + +/* line 123, ../scss/Layer.scss */ +.collapsible-clicker { + position: absolute; + width: 10px; + height: 10px; + top: 5px; + left: 5px; + margin: 0px; + padding: 0px; + background-image: url(../images/icon-open.png); + background-repeat: no-repeat; +} + +/* line 134, ../scss/Layer.scss */ +.collapsible-clicker.collapsible-collapsed { + background-image: url(../images/icon-collapsed.png); +} + +/* line 137, ../scss/Layer.scss */ +.collapsible-content .collapsible-clicker { + left: 12px; +} + +/* line 140, ../scss/Layer.scss */ +.content-layer.collapsible-collapsed { + height: 0px; + overflow: hidden; +} + +/* line 146, ../scss/Layer.scss */ +.label-layer .cssbutton, +.label-style .cssbutton { + width: 14px; + height: 14px; + overflow: hidden; + position: absolute; + background-repeat: no-repeat; +} + +/* line 153, ../scss/Layer.scss */ +.label-layer .button-lock { + background-image: url(../images/icon-lock.png); + top: 3px; + right: 27px; +} + +/* line 158, ../scss/Layer.scss */ +.label-layer .button-visible { + background-image: url(../images/icon-eye.png); + top: 3px; + right: 7px; +} + +/* line 163, ../scss/Layer.scss */ +.label-style .button-add { + background-image: url(../images/icon-plus.png); + width: 15px; + height: 15px; + top: 3px; + right: 11px; +} + +/* line 170, ../scss/Layer.scss */ +.label-style .button-delete { + background-image: url(../images/icon-minus.png); + width: 15px; + height: 15px; + top: 3px; + right: 31px; +} + +/* line 177, ../scss/Layer.scss */ +.collapsible-content .layout-table { + width: 99.9%; +} + +/* line 180, ../scss/Layer.scss */ +.content-layer .collapsible-content { + padding-left: 30px; +} + +/* line 183, ../scss/Layer.scss */ +.collapsible-content .collapsible-content .layout-table .layout-row .layout-cell { + width: 40%; + height: 20px; + border-bottom: 1px solid #505050; + line-height: 20px; + text-align: left; +} + +/* line 190, ../scss/Layer.scss */ +.collapsible-content .layout-table:first-child { + border-top: 1px solid #505050; +} + +/* line 193, ../scss/Layer.scss */ +.collapsible-transition { + -webkit-transition-property: height; + -webkit-transition-duration: 200ms; + -webkit-transition-timing-function: ease-in; +} + +/* line 199, ../scss/Layer.scss */ +.editable2 { + height: 20px; + background-color: #242424 !important; + color: #b2b2b2 !important; + border-width: 0px; + font-size: 11px; + overflow: hidden; + -webkit-user-select: text; + text-overflow: clip; +} + +/* styles elements */ +/* line 211, ../scss/Layer.scss */ +.content-style .item-template { + display: none; +} + +/* line 214, ../scss/Layer.scss */ +.content-style .layout-row.selected .layout-cell { + background-color: #b2b2b2; + color: #242424; +} + +/* line 218, ../scss/Layer.scss */ +.style-row { + height: 20px; +} diff --git a/js/panels/Timeline/Layer.reel/images/eye.png b/js/panels/Timeline/Layer.reel/images/eye.png new file mode 100644 index 00000000..8ec1759e Binary files /dev/null and b/js/panels/Timeline/Layer.reel/images/eye.png differ diff --git a/js/panels/Timeline/Layer.reel/images/icon-collapsed.png b/js/panels/Timeline/Layer.reel/images/icon-collapsed.png new file mode 100644 index 00000000..d2823a89 Binary files /dev/null and b/js/panels/Timeline/Layer.reel/images/icon-collapsed.png differ diff --git a/js/panels/Timeline/Layer.reel/images/icon-eye.png b/js/panels/Timeline/Layer.reel/images/icon-eye.png new file mode 100644 index 00000000..6178654e Binary files /dev/null and b/js/panels/Timeline/Layer.reel/images/icon-eye.png differ diff --git a/js/panels/Timeline/Layer.reel/images/icon-lock.png b/js/panels/Timeline/Layer.reel/images/icon-lock.png new file mode 100644 index 00000000..e06b4f22 Binary files /dev/null and b/js/panels/Timeline/Layer.reel/images/icon-lock.png differ diff --git a/js/panels/Timeline/Layer.reel/images/icon-minus.png b/js/panels/Timeline/Layer.reel/images/icon-minus.png new file mode 100644 index 00000000..20a047f5 Binary files /dev/null and b/js/panels/Timeline/Layer.reel/images/icon-minus.png differ diff --git a/js/panels/Timeline/Layer.reel/images/icon-open.png b/js/panels/Timeline/Layer.reel/images/icon-open.png new file mode 100644 index 00000000..8dc14271 Binary files /dev/null and b/js/panels/Timeline/Layer.reel/images/icon-open.png differ diff --git a/js/panels/Timeline/Layer.reel/images/icon-plus.png b/js/panels/Timeline/Layer.reel/images/icon-plus.png new file mode 100644 index 00000000..ad1381b9 Binary files /dev/null and b/js/panels/Timeline/Layer.reel/images/icon-plus.png differ diff --git a/js/panels/Timeline/Layer.reel/images/lock_closed.png b/js/panels/Timeline/Layer.reel/images/lock_closed.png new file mode 100644 index 00000000..8ff213b7 Binary files /dev/null and b/js/panels/Timeline/Layer.reel/images/lock_closed.png differ diff --git a/js/panels/Timeline/Layer.reel/images/lock_open.png b/js/panels/Timeline/Layer.reel/images/lock_open.png new file mode 100644 index 00000000..9db30f8d Binary files /dev/null and b/js/panels/Timeline/Layer.reel/images/lock_open.png differ diff --git a/js/panels/Timeline/Layer.reel/images/panelDisclosureIcon.png b/js/panels/Timeline/Layer.reel/images/panelDisclosureIcon.png new file mode 100644 index 00000000..4db78f13 Binary files /dev/null and b/js/panels/Timeline/Layer.reel/images/panelDisclosureIcon.png differ diff --git a/js/panels/Timeline/Layer.reel/scss/Layer.scss b/js/panels/Timeline/Layer.reel/scss/Layer.scss new file mode 100644 index 00000000..7473a275 --- /dev/null +++ b/js/panels/Timeline/Layer.reel/scss/Layer.scss @@ -0,0 +1,220 @@ +@charset "UTF-8"; + +/* Layer.scss + * Main SCSS file for Layer component, compiled by SASS into the file css/Layer.css. + */ + +// Import theme settings +@import "../../../../../_scss/imports/themes/default/colors"; +// @import "../../../../../_scss/imports/themes/default/fonts"; +@import "../../../../../_scss/imports/themes/default/mixins"; + +// Import generic mixins and styles +@i