APIs

Show:
  1. /**
  2. The class generates the UI for a template (a.k.a Screen Division) that is
  3. a selectable widget including the drawing of each viewer (division) within
  4. the screen, as well as firing related click events on action.
  5. @class ScreenTemplateFactory
  6. @constructor
  7. @param {object} i_screenTemplateData hold data as instructions for factory creation component
  8. @param {String} i_type the type of widget that we will create. This includes
  9. VIEWER_SELECTABLE as well as ENTIRE_SELECTABLE with respect to the ability to select the components viewers individually
  10. or the entire screen division
  11. @param {object} i_owner the owner of this class (parent) that we can query at the listening end, to examine if the event is
  12. of any interest to the listener.
  13. **/
  14. define(['jquery', 'backbone'], function ($, Backbone) {
  15.  
  16. /**
  17. This is a key event in the framework as many different instances subscribe to ON_VIEWER_SELECTED to reconfigure
  18. themselves. The event is fired when a viewer (i.e.: a screen division) is selected inside a Template (i.e. Screen).
  19. The key to remember is that the Factory instance (this) is always created with respect to it's owner (i_owner),
  20. so when ON_VIEWER_SELECTED is fired, the owner is carried with the event so listeners can act accordingly, and only if the owner
  21. is of interest to a subscribed listener.
  22. @event ON_VIEWER_SELECTED
  23. @param {this} caller
  24. @param {object} screenData event params
  25. @static
  26. @final
  27. @param {screenData} json encapsulated data of entire configuration of instance
  28. **/
  29. BB.EVENTS.ON_VIEWER_SELECTED = 'ON_VIEWER_SELECTED';
  30.  
  31. var ScreenTemplateFactory = BB.Controller.extend({
  32.  
  33. /**
  34. Constructor
  35. @method initialize
  36. **/
  37. initialize: function () {
  38. var self = this;
  39. this.m_owner = self.options.i_owner;
  40. this.m_myElementID = 'svgScreenLayout' + '_' + _.uniqueId();
  41. this.m_screenTemplateData = self.options.i_screenTemplateData;
  42. this.m_selfDestruct = self.options.i_selfDestruct;
  43. this.m_orientation = self.options.i_screenTemplateData['orientation'];
  44. this.m_resolution = self.options.i_screenTemplateData['resolution'];
  45. this.m_screenProps = self.options.i_screenTemplateData['screenProps'];
  46. this.m_scale = self.options.i_screenTemplateData['scale'];
  47. this.m_svgWidth = (this.m_resolution.split('x')[0]) / this.m_scale;
  48. this.m_svgHeight = (this.m_resolution.split('x')[1]) / this.m_scale;
  49. this.m_useLabels = false;
  50. },
  51.  
  52. /**
  53. Get current selection color depnding on theme of light / daek
  54. @method _getColor
  55. @params {String} color
  56. _getColor: function(){
  57. if (BB.CONSTS['THEME']=='light')
  58. return '#428ac9 ';
  59. return '#eb7c66';
  60. },
  61. **/
  62.  
  63. /**
  64. Method is called when an entire screen frame of the UI is clicked, in contrast to when a single viewer is selected.
  65. The difference in dispatch of the event depends on how the factory created this instance.
  66. @method _onViewSelected
  67. @param {Event} e
  68. @param {Object} i_caller
  69. @return {Boolean} false
  70. **/
  71. _onViewSelected: function (e, i_caller) {
  72. var self = i_caller;
  73. var element = e.target;
  74.  
  75. var campaign_timeline_board_viewer_id = $(element).data('campaign_timeline_board_viewer_id');
  76. var campaign_timeline_id = $(element).data('campaign_timeline_id');
  77.  
  78. var screenData = {
  79. sd: $(element).data('sd'),
  80. elementID: i_caller.m_myElementID,
  81. owner: i_caller.getOwner(),
  82. campaign_timeline_board_viewer_id: campaign_timeline_board_viewer_id,
  83. campaign_timeline_id: campaign_timeline_id,
  84. screenTemplateData: self.m_screenTemplateData
  85. };
  86. self._deselectViewers();
  87. BB.comBroker.fire(BB.EVENTS.ON_VIEWER_SELECTED, this, screenData);
  88. },
  89.  
  90. /**
  91. Deselect all viewers, thus change their colors back to default.
  92. @method _deselectViewers
  93. @return none
  94. **/
  95. _deselectViewers: function () {
  96. var self = this;
  97. $(Elements.CLASS_SCREEN_DIVISION).each(function () {
  98. if ($(this).is('rect')) {
  99. $(this).css({'fill': 'rgb(230,230,230)'});
  100. }
  101. });
  102. },
  103.  
  104. /**
  105. When enabled, _mouseOverEffect will highlight viewers when mouse is hovered over them.
  106. @method _mouseOverEffect
  107. @return none
  108. **/
  109. _mouseOverEffect: function () {
  110. var self = this;
  111. var a = $('#' + self.m_myElementID);
  112. var b = $('#' + self.m_myElementID).find('rect');
  113. $('#' + self.m_myElementID).find('rect').each(function () {
  114. $(this).on('mouseover', function () {
  115. $(this).css({'fill': 'rgb(190,190,190)'});
  116. }).mouseout(function () {
  117. $(this).css({'fill': 'rgb(230,230,230)'});
  118. });
  119. });
  120. },
  121.  
  122. /**
  123. Get the owner (parent) of this instance, i.e., the one who created this.
  124. We use the owner attribute as a way to distinguish what type of instance this was created as.
  125. @method getOwner
  126. @return {Object} m_owner
  127. **/
  128. getOwner: function () {
  129. var self = this;
  130. return self.m_owner;
  131. },
  132.  
  133. /**
  134. Create all the screen divisions (aka viewers) as svg snippets and push them into an array
  135. @method getDivisions
  136. @return {array} f array of all svg divisions
  137. **/
  138. getDivisions: function () {
  139. var self = this;
  140. var svg = self.create();
  141. return $(svg).find('rect');
  142.  
  143. var f = $(svg).find('rect').map(function (k, v) {
  144. return '<svg style="padding: 0px; margin: 15px" width="20px" height="20px" xmlns="http://www.w3.org/2000/svg"> ' +
  145. '<g>' +
  146. v.outerHTML +
  147. '</g> ' +
  148. '</svg>';
  149. });
  150. return f;
  151. },
  152.  
  153. /**
  154. Create will produce the actual SVG based Template (screen) with inner viewers and return HTML snippet to the caller.
  155. @method create
  156. @return {Object} html element produced by this factory
  157. **/
  158. create: function () {
  159. var self = this;
  160. var screensDivisons = '';
  161. var screenLabels = '';
  162.  
  163. // sort for proper z-order creating the viewers
  164. var orderedScreenValues = [], i = 0;
  165. for (var screenValues in self.m_screenProps) {
  166. var viewOrder = self.m_screenProps[screenValues]['view_order'];
  167. viewOrder = _.isUndefined(viewOrder) ? i : viewOrder;
  168. orderedScreenValues[viewOrder] = self.m_screenProps[screenValues];
  169. i++;
  170. }
  171.  
  172. // create the viewers
  173. i = 0;
  174. for (var ordered in orderedScreenValues) {
  175. i++;
  176. var screenValue = orderedScreenValues[ordered];
  177. var x = screenValue['x'] == 0 ? 0 : screenValue['x'] / self.m_scale;
  178. var y = screenValue['y'] == 0 ? 0 : screenValue['y'] / self.m_scale;
  179. var w = screenValue['w'] == 0 ? 0 : screenValue['w'] / self.m_scale;
  180. var h = screenValue['h'] == 0 ? 0 : screenValue['h'] / self.m_scale;
  181. var campaign_timeline_board_viewer_id = screenValue['campaign_timeline_board_viewer_id'];
  182. var campaign_timeline_id = screenValue['campaign_timeline_id'];
  183. var sd = screenValues;
  184.  
  185. var uniqueID = 'rectSD' + '_' + _.uniqueId();
  186. if (self.m_useLabels == true)
  187. screenLabels += '<text class="screenDivisionClass"' + '" data-for="' + uniqueID + '" x="' + (x + (w / 2)) + '" y="' + (y + (h / 2)) + '" font-family="sans-serif" font-size="12px" text-anchor="middle" alignment-baseline="middle" fill="#666">' + i + '</text>';
  188.  
  189. screensDivisons += '<rect id="' + uniqueID +
  190. '" data-campaign_timeline_board_viewer_id="' + campaign_timeline_board_viewer_id +
  191. '" data-campaign_timeline_id="' + campaign_timeline_id +
  192. '" x="' + x +
  193. '" y="' + y +
  194. '" width="' + w +
  195. '" height="' + h +
  196. '" data-sd="' + sd +
  197. '" class="screenDivisionClass"' +
  198. ' style="fill:rgb(230,230,230);stroke-width:2;stroke:rgb(72,72,72)"/>';
  199. }
  200. return ($('<svg class="svgSD" id="' + self.m_myElementID + '" width="' + self.m_svgWidth + '" height="' + self.m_svgHeight + '" xmlns="http://www.w3.org/2000/svg"> ' +
  201. '<g>' +
  202. screensDivisons +
  203. screenLabels +
  204. '</g> ' +
  205. '</svg>'));
  206. },
  207.  
  208. /**
  209. When enabled, selectableFrame will allow for UI mouse / click of the outer frame of the template (screen) and not
  210. individual viewers.
  211. @method selectableFrame
  212. @return none
  213. **/
  214. selectableFrame: function () {
  215. var self = this;
  216. var applyToSelected = function (e) {
  217. $('#' + self.m_myElementID).parent().parent().parent().find('rect').css({'stroke-width': '2', 'stroke': 'rgb(72,72,72)'});
  218. $('#' + self.m_myElementID).find('rect').css({'stroke-width': '2', 'stroke': BB.lib.getThemeColor()});
  219. self._onViewSelected(e, self);
  220. }
  221. // listen one
  222. if (self.m_selfDestruct) {
  223. $(Elements.CLASS_SCREEN_DIVISION, '#' + self.m_myElementID).one('mouseup contextmenu', function (e) {
  224. applyToSelected(e);
  225. });
  226.  
  227. } else {
  228. // listen on
  229. $(Elements.CLASS_SCREEN_DIVISION, '#' + self.m_myElementID).on('mouseup contextmenu', function (e) {
  230. applyToSelected(e);
  231. });
  232. }
  233. },
  234.  
  235. /**
  236. The public method version of _deselectViewers, which de-selects all viewers
  237. @method deselectDivisons
  238. **/
  239. deselectDivisons: function () {
  240. var self = this;
  241. self._deselectViewers();
  242. },
  243.  
  244. /**
  245. Select a division (aka viewer) using it's viewer_id, only applicable when class represents an actual timelime > board > viewer_id
  246. @method selectDivison
  247. @param {Number} i_campaign_timeline_board_viewer_id
  248. **/
  249. selectDivison: function (i_campaign_timeline_board_viewer_id) {
  250. var self = this;
  251. self._deselectViewers();
  252. var selectedElement = $('#' + self.m_myElementID).find('[data-campaign_timeline_board_viewer_id="' + i_campaign_timeline_board_viewer_id + '"]');
  253. $(selectedElement).css({'fill': BB.lib.getThemeColor()});
  254. },
  255.  
  256. /**
  257. Release all members to allow for garbage collection.
  258. @method destroy
  259. @return none
  260. **/
  261. destroy: function () {
  262. var self = this;
  263. $(Elements.CLASS_SCREEN_DIVISION).off('click contextmenu', function (e) {
  264. self._onViewSelected(e, self);
  265. });
  266. $(this).off('mouseover', function () {
  267. $(this).css({'fill': 'rgb(190,190,190)'});
  268. }).mouseout(function () {
  269. $(this).css({'fill': 'rgb(230,230,230)'});
  270. });
  271. $.each(self, function (k) {
  272. self[k] = undefined;
  273. });
  274. }
  275. });
  276.  
  277. return ScreenTemplateFactory;
  278.  
  279. });