'use strict'; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** * Licensed Materials - Property of IBM * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2019 * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */ define(['underscore', 'gemini/lib/@waca/dashboard-common/dist/core/APIFactory', 'gemini/lib/@waca/dashboard-common/dist/api/PropertiesProviderAPI'], function (_, APIFactory, PropertiesProviderAPI) { var TimelinePropertiesProvider = function () { function TimelinePropertiesProvider(options) { _classCallCheck(this, TimelinePropertiesProvider); this.dashboardApi = options.dashboardAPI; this.content = options.content; this.stringResources = this.dashboardApi.getFeature('.StringResources'); this._api = APIFactory.createAPI(this, [PropertiesProviderAPI]); // register self as a properties provider contributing timeline properties this.content.getFeature('Properties').registerProvider(this.getAPI()); } TimelinePropertiesProvider.prototype.getAPI = function getAPI() { return this._api; }; TimelinePropertiesProvider.prototype.getPropertyLayoutList = function getPropertyLayoutList() { return [{ id: 'animation', type: 'Group', label: this.stringResources.get('tabName_animation') }, { id: 'propAniEntrance', type: 'Section', label: this.stringResources.get('propAniEntrance'), position: 1 }, { id: 'propAniExit', type: 'Section', label: this.stringResources.get('propAniExit'), position: 2 }]; }; TimelinePropertiesProvider.prototype.getPropertyList = function getPropertyList() { return this._getTimelineProperties(); }; TimelinePropertiesProvider.prototype._getTimelineProperties = function _getTimelineProperties() { var properties = []; var timelineController = this.dashboardApi.getFeature('.StoryPaneService').timelineController; var episode = timelineController.getTimelineEpisodeById(this.content.getId()); if (episode) { var duration = timelineController.getDuration(); if (episode.touchesStart()) { properties.push({ id: 'noEntranceAnimation', editor: { sectionId: 'animation.propAniEntrance', readOnly: true, position: 1, uiControl: { type: 'SectionLabel', label: this.stringResources.get('animationNoEntranceText'), tabName: this.stringResources.get('tabName_animation'), sectionName: this.stringResources.get('propAniEntrance') } } }); } else { properties.push.apply(properties, this._getEntranceSectionItems(episode.getEntranceAct(), this.content)); } if (episode.touchesEnd(duration)) { properties.push({ id: 'noExitAnimation', editor: { sectionId: 'animation.propAniExit', readOnly: true, position: 1, uiControl: { type: 'SectionLabel', label: this.stringResources.get('animationNoExitText'), tabName: this.stringResources.get('tabName_animation'), sectionName: this.stringResources.get('propAniExit') } } }); } else { properties.push.apply(properties, this._getExitSectionItems(episode.getExitAct(), this.content)); } properties.push.apply(properties, this._getAnimationTimeProperties(episode, timelineController)); } return properties; }; TimelinePropertiesProvider.prototype._getEntranceSectionItems = function _getEntranceSectionItems(act, content) { var _this = this; var initialEntranceAnimation = act.action || 'show'; var initialEntranceDirection = null; if (initialEntranceAnimation.indexOf('slide') >= 0) { initialEntranceDirection = initialEntranceAnimation; initialEntranceAnimation = 'slideIn'; } return [{ id: 'animationEntranceType', getPropertyValue: function getPropertyValue() { return initialEntranceAnimation; }, setPropertyValue: function setPropertyValue(value) { if (value === 'slideIn') { value = content.getPropertyValue('animationEntranceDirection') || 'slideInLeft'; } _this._updateActModel(act, { 'action': value }); }, editor: { sectionId: 'animation.propAniEntrance', position: 1, uiControl: { type: 'DropDown', name: 'animationEntranceType', label: this.stringResources.get('propAniAnimation'), ariaLabel: this.stringResources.get('propAniTypeEntrance'), options: [{ label: this.stringResources.get('propAniTypeEntranceFadeIn'), value: 'show' }, { label: this.stringResources.get('propAniTypeEntranceSlideIn'), value: 'slideIn' }, { label: this.stringResources.get('propAniTypeEntranceScaleIn'), value: 'scaleIn' }, { label: this.stringResources.get('propAniTypeEntranceShrinkIn'), value: 'shrinkIn' }, { label: this.stringResources.get('propAniTypeEntrancePivotIn'), value: 'pivotIn' }], onChange: function onChange(propertyName, propertyValue) { _this.dashboardApi.triggerDashboardEvent('properties:updateEnabled', { propertyName: 'animationEntranceDirection', enabled: propertyValue === 'slideIn' }); _this.content.setPropertyValue(propertyName, propertyValue); } } } }, { id: 'animationEntranceDirection', getPropertyValue: function getPropertyValue() { return initialEntranceDirection; }, setPropertyValue: function setPropertyValue(value) { return _this._updateActModel(act, { 'action': value }); }, editor: { sectionId: 'animation.propAniEntrance', position: 2, uiControl: { type: 'DropDown', name: 'animationEntranceDirection', label: this.stringResources.get('propAniDirection'), ariaLabel: this.stringResources.get('propAniDirectionIn'), disabled: initialEntranceAnimation !== 'slideIn', options: [{ label: this.stringResources.get('propAniDirectionInLeft'), value: 'slideInLeft' }, { label: this.stringResources.get('propAniDirectionInRight'), value: 'slideInRight' }, { label: this.stringResources.get('propAniDirectionInTop'), value: 'slideInTop' }, { label: this.stringResources.get('propAniDirectionInBottom'), value: 'slideInBottom' }] } } }]; }; TimelinePropertiesProvider.prototype._getExitSectionItems = function _getExitSectionItems(act, content) { var _this2 = this; var initialExitAnimation = act.action || 'hide'; var initialExitDirection = null; if (initialExitAnimation.indexOf('slide') >= 0) { initialExitDirection = initialExitAnimation; initialExitAnimation = 'slideOut'; } return [{ id: 'animationExitType', getPropertyValue: function getPropertyValue() { return initialExitAnimation; }, setPropertyValue: function setPropertyValue(value) { if (value === 'slideOut') { value = content.getPropertyValue('animationExitDirection') || 'slideOutLeft'; } _this2._updateActModel(act, { 'action': value }); }, editor: { sectionId: 'animation.propAniExit', position: 1, uiControl: { type: 'DropDown', name: 'animationExitType', label: this.stringResources.get('propAniAnimation'), ariaLabel: this.stringResources.get('propAniTypeExit'), options: [{ label: this.stringResources.get('propAniTypeExitFadeIn'), value: 'hide' }, { label: this.stringResources.get('propAniTypeExitSlideIn'), value: 'slideOut' }, { label: this.stringResources.get('propAniTypeExitScaleIn'), value: 'scaleOut' }, { label: this.stringResources.get('propAniTypeExitExpandOut'), value: 'expandOut' }, { label: this.stringResources.get('propAniTypeExitPivotOut'), value: 'pivotOut' }], onChange: function onChange(propertyName, propertyValue) { _this2.dashboardApi.triggerDashboardEvent('properties:updateEnabled', { propertyName: 'animationExitDirection', enabled: propertyValue === 'slideOut' }); _this2.content.setPropertyValue(propertyName, propertyValue); } } } }, { id: 'animationExitDirection', getPropertyValue: function getPropertyValue() { return initialExitDirection; }, setPropertyValue: function setPropertyValue(value) { return _this2._updateActModel(act, { 'action': value }); }, editor: { sectionId: 'animation.propAniExit', position: 2, uiControl: { type: 'DropDown', name: 'animationExitDirection', label: this.stringResources.get('propAniDirection'), ariaLabel: this.stringResources.get('propAniDirectionOut'), disabled: initialExitAnimation !== 'slideOut', options: [{ label: this.stringResources.get('propAniDirectionOutLeft'), value: 'slideOutLeft' }, { label: this.stringResources.get('propAniDirectionOutRight'), value: 'slideOutRight' }, { label: this.stringResources.get('propAniDirectionOutTop'), value: 'slideOutTop' }, { label: this.stringResources.get('propAniDirectionOutBottom'), value: 'slideOutBottom' }] } } }]; }; TimelinePropertiesProvider.prototype._getAnimationTimeProperties = function _getAnimationTimeProperties(episode, timelineController) { var _this3 = this; return [{ id: 'animationEntranceTime', getPropertyValue: function getPropertyValue() { return _this3._getValueString(episode.getEntranceAct().timer); }, setPropertyValue: function setPropertyValue(value, act) { void act; //TODO this should be in the episode... or the act itself timelineController.updateTimelineDuration(_this3.content.getId(), value, episode.getExitAct().timer, { skipUndoRedo: true }); }, editor: { sectionId: 'animation.propAniEntrance', position: 3, uiControl: { type: 'InputLabel', name: 'animationEntranceTime', label: this.stringResources.get('propAniEntranceTime'), ariaLabel: this.stringResources.get('propAniEntranceTime'), decimalPlaces: 15, // Maxed to avoid Glass interfering with our number processing (see Glass's BaseProperty:_onBlur()) handleReturnKey: true, onChange: function onChange(propertyName, propertyValue) { var act = episode.getEntranceAct(); var value = 1000 * parseFloat(propertyValue); // Seconds to milliseconds, ignoring any trailing non-digits value = _this3._validateTimerValue(value, episode, 'Entrance'); if (value != null) { // Update model and refresh properties if a change occurs vis-à-vis the episode touching the beginning or end var oldTouch = episode.touchesStart() + episode.touchesEnd(timelineController.getDuration()); _this3.content.setPropertyValue(propertyName, value, act); var newTouch = episode.touchesStart() + episode.touchesEnd(timelineController.getDuration()); if (newTouch != oldTouch) { _this3.dashboardApi.triggerDashboardEvent('properties:refreshPane'); } } // Update UI var uiValue = _this3._getValueString(act.timer); _this3.dashboardApi.triggerDashboardEvent('properties:setValue', { propertyName: propertyName, value: uiValue }); } } } }, { id: 'animationExitTime', getPropertyValue: function getPropertyValue() { return _this3._getValueString(episode.getExitAct().timer); }, setPropertyValue: function setPropertyValue(value, act) { void act; //TODO this should be in the episode... or the act itself timelineController.updateTimelineDuration(_this3.content.getId(), episode.getEntranceAct().timer, value, { skipUndoRedo: true }); }, editor: { sectionId: 'animation.propAniExit', position: 3, uiControl: { type: 'InputLabel', name: 'animationExitTime', label: this.stringResources.get('propAniExitTime'), ariaLabel: this.stringResources.get('propAniExitTime'), decimalPlaces: 15, // Maxed to avoid Glass interfering with our number processing (see Glass's BaseProperty:_onBlur()) handleReturnKey: true, onChange: function onChange(propertyName, propertyValue) { var act = episode.getExitAct(); var value = 1000 * parseFloat(propertyValue); // Seconds to milliseconds, ignoring any trailing non-digits value = _this3._validateTimerValue(value, episode, 'Exit'); if (value != null) { // Update model and refresh properties if a change occurs vis-à-vis the episode touching the beginning or end var oldTouch = episode.touchesStart() + episode.touchesEnd(timelineController.getDuration()); _this3.content.setPropertyValue(propertyName, value, act); var newTouch = episode.touchesStart() + episode.touchesEnd(timelineController.getDuration()); if (newTouch != oldTouch) { _this3.dashboardApi.triggerDashboardEvent('properties:refreshPane'); } } // Update UI var uiValue = _this3._getValueString(act.timer); _this3.dashboardApi.triggerDashboardEvent('properties:setValue', { propertyName: propertyName, value: uiValue }); } } } }]; }; TimelinePropertiesProvider.prototype._getValueString = function _getValueString(value) { return (parseFloat(value) / 1000).toFixed(2); }; TimelinePropertiesProvider.prototype._validateTimerValue = function _validateTimerValue(value, episode, type) { var tick = 50; // snap values to nearest tick // tick must match _tickLength value set in TimeQueue.js:init() // TODO: Refactor to better deal with shared constants like this var minDuration = 200; // exit - entrance > minDuration if (isNaN(value)) { return null; } // Round number to nearest acceptable value // - nearest tick // - episode lasts at least for minDuration // - non-negative var rounded = tick * Math.round(value / tick); if (type == 'Entrance' && rounded >= episode.getExitAct().timer - minDuration) { rounded = episode.getExitAct().timer - minDuration; } if (type == 'Exit' && rounded <= episode.getEntranceAct().timer + minDuration) { rounded = episode.getEntranceAct().timer + minDuration; } if (rounded < 0) { rounded = 0; } return rounded; }; TimelinePropertiesProvider.prototype._updateActModel = function _updateActModel(act, update) { act.set(update, { payloadData: { undoRedoTransactionId: _.uniqueId('_animationProp_'), // TODO: fix this. the property pane should always be in sync with the model. // at this point if we refresh it causes ugly flicker so I'm leaving this here. // // disable undo/redo for now since the property pane gets out of sync // with the model. skipUndoRedo: true } }); }; return TimelinePropertiesProvider; }(); return TimelinePropertiesProvider; }); //# sourceMappingURL=TimelinePropertiesProvider.js.map