LassoSelectView.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /**
  2. * Licensed Materials - Property of IBM
  3. *
  4. * IBM Cognos Products: BI
  5. *
  6. * Copyright IBM Corp. 2017
  7. *
  8. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  9. */
  10. /**
  11. * @file Lasso selection view
  12. */
  13. 'use strict';
  14. define(['../../../lib/@waca/core-client/js/core-client/ui/View', 'jquery', '../../../lib/@waca/core-client/js/core-client/utils/BrowserUtils', '../../../lib/@waca/dashboard-common/dist/utils/EventChainLocal'], function (BaseView, $, BrowserUtils, EventChainLocal) {
  15. var keyCodes = {
  16. LEFT_CLICK: 1,
  17. ESCAPE: 27
  18. };
  19. var POINTER_EVENTS = {
  20. DOWN: 'mousedown touchstart',
  21. MOVE: 'mousemove touchmove',
  22. UP: 'mouseup touchend',
  23. LEAVE: 'mouseleave'
  24. };
  25. var LassoSelectView = BaseView.extend({
  26. id: 'lw-lasso-select',
  27. /**
  28. * @param {options} set of initial properties
  29. *
  30. */
  31. init: function init($target, cordinateResolver, isDragging) {
  32. BaseView.inherited('init', this, arguments);
  33. this.$el.prependTo(document.body);
  34. this.$target = $target;
  35. this.targetNode = this.$target.get(0);
  36. this.$body = $(document.body);
  37. this.cordinateResolver = cordinateResolver;
  38. this._isDragging = isDragging;
  39. this.handlers = {
  40. mousemove: this._getPipedHandler(this._handleMouseMove),
  41. mouseup: this._getPipedHandler(this._handleMouseUp),
  42. mousedown: this._getPipedHandler(this._handleMouseDown),
  43. keyup: this._getPipedHandler(this._handleKeyup),
  44. mouseleave: this._getPipedHandler(this._handleMouseLeave)
  45. };
  46. if (!this._isIE()) {
  47. this._configCursor();
  48. }
  49. this.$el.on(POINTER_EVENTS.MOVE, this.handlers.mousemove);
  50. this.$body.keyup(this.handlers.keyup);
  51. this.$target.on(POINTER_EVENTS.LEAVE, this.handlers.mouseleave).on(POINTER_EVENTS.MOVE, this.handlers.mousemove).on(POINTER_EVENTS.DOWN, this.handlers.mousedown);
  52. },
  53. /**
  54. * Mouse move event handler
  55. * @param {Object} event Jquery event object
  56. */
  57. _handleMouseMove: function _handleMouseMove(event) {
  58. this._updateCursor(event);
  59. var left = Math.min(event.pageX, this.left);
  60. var top = Math.min(event.pageY, this.top);
  61. var width = Math.abs(event.pageX - this.left);
  62. var height = Math.abs(event.pageY - this.top);
  63. var cssUpdate = {
  64. left: left,
  65. top: top,
  66. width: width,
  67. height: height
  68. };
  69. if (this._isDragging(event)) {
  70. this.$el.css(cssUpdate);
  71. if (this._isLassoWithinTarget()) {
  72. this.trigger('lassoSelect:cordsChange', { event: event, cords: this._getCords() });
  73. }
  74. }
  75. },
  76. /**
  77. * Handle key up event
  78. * @param {Object} event Jquery event object
  79. */
  80. _handleKeyup: function _handleKeyup(e) {
  81. if (e.keyCode === keyCodes.ESCAPE) {
  82. this.trigger('lassoSelect:cancel', {});
  83. }
  84. },
  85. /**
  86. * Mouse up event handler
  87. * @param {Object} event Jquery event object
  88. */
  89. _handleMouseUp: function _handleMouseUp(event) {
  90. if (this._isLassoWithinTarget()) {
  91. this.trigger('lassoSelect:done', { event: event, cords: this._getCords() });
  92. }
  93. var cssUpdate = {
  94. left: 0,
  95. top: 0,
  96. width: 0,
  97. height: 0
  98. };
  99. this.$el.css(cssUpdate);
  100. this.$body.off(POINTER_EVENTS.UP, this.handlers.mouseup);
  101. },
  102. /**
  103. * Mouse down event handler
  104. * @param {Object} event Jquery event object
  105. */
  106. _handleMouseDown: function _handleMouseDown(event) {
  107. if (event.type === 'touchstart' || event.which === keyCodes.LEFT_CLICK) {
  108. this.left = event.pageX;
  109. this.top = event.pageY;
  110. this.$body.on(POINTER_EVENTS.UP, this.handlers.mouseup);
  111. }
  112. },
  113. _handleMouseLeave: function _handleMouseLeave(event) {
  114. this._updateCursor(event, false);
  115. },
  116. remove: function remove() {
  117. this.$el.off(POINTER_EVENTS.MOVE, this.handlers.mousemove);
  118. this.$body.off(POINTER_EVENTS.UP, this.handlers.mouseup).off('keyup', this.handlers.keyup);
  119. this.$target.off(POINTER_EVENTS.DOWN, this.handlers.mousedown).off(POINTER_EVENTS.LEAVE, this.handlers.mouseleave).off(POINTER_EVENTS.MOVE, this.handlers.mousemove);
  120. if (this._initCursor) {
  121. this.targetNode.style.cursor = this._initCursor.target;
  122. }
  123. this.handlers = null;
  124. if (this.$cursor) {
  125. this.$cursor.remove();
  126. this.$cursor = null;
  127. }
  128. BaseView.inherited('remove', this, arguments);
  129. },
  130. /**
  131. * Returns the co-ordinate of the polygon (square) forming the lasso selection
  132. */
  133. _getCords: function _getCords() {
  134. var rect = this.el.getBoundingClientRect();
  135. var cords = [{ x: rect.left, y: rect.top }, // left top
  136. { x: rect.right, y: rect.top }, // right top
  137. { x: rect.right, y: rect.bottom }, // right bottom
  138. { x: rect.left, y: rect.bottom // left bottom
  139. }];
  140. return cords;
  141. },
  142. /**
  143. * Returns true if the event lasso area is within the target region
  144. */
  145. _isLassoWithinTarget: function _isLassoWithinTarget() {
  146. var targetRectCord = this.$target.get(0).getBoundingClientRect();
  147. var lassoRectCord = this.el.getBoundingClientRect();
  148. return lassoRectCord.top >= targetRectCord.top && lassoRectCord.left >= targetRectCord.left && lassoRectCord.right <= targetRectCord.right && lassoRectCord.bottom <= targetRectCord.bottom;
  149. },
  150. /**
  151. *
  152. * Pass handler through a pipe
  153. * @param handler - input handler function
  154. * @return Handler function which executes logic before calling the input handler.
  155. */
  156. _getPipedHandler: function _getPipedHandler(handler) {
  157. var func = function func(event) {
  158. if (this._isTouch(event)) {
  159. event.preventDefault();
  160. this.cordinateResolver(event);
  161. }
  162. // Lasso interaction don't deselect the widget
  163. var eventChainLocal = new EventChainLocal(event);
  164. eventChainLocal.setProperty('preventWidgetDeselect', true);
  165. handler.bind(this)(event);
  166. };
  167. return func.bind(this);
  168. },
  169. _isTouch: function _isTouch(event) {
  170. return event.type && (event.type === 'touchstart' || event.type === 'touchmove' || event.type === 'touchend');
  171. },
  172. _updateCursor: function _updateCursor(event, show) {
  173. if (!this._isIE()) {
  174. return;
  175. }
  176. var OFFSET = {
  177. LEFT: 10,
  178. TOP: 12
  179. };
  180. if (show === false) {
  181. if (this.$cursor) {
  182. this.$cursor.hide();
  183. }
  184. return;
  185. }
  186. if (this.$cursor && !this.$cursor.is(':visible')) {
  187. this.$cursor.show();
  188. } else if (!this.$cursor) {
  189. this.$cursor = $('<div class="lassoIconBox">');
  190. this.$cursor.prependTo(document.body);
  191. }
  192. this.$cursor.css({ left: event.pageX + OFFSET.LEFT, top: event.pageY + OFFSET.TOP });
  193. },
  194. _isIE: function _isIE() {
  195. return BrowserUtils.isIE();
  196. },
  197. _configCursor: function _configCursor() {
  198. var curVal = 'url(dashboard-analytics/images/pointer-marquee_32.svg), auto';
  199. this._initCursor = {};
  200. this._initCursor.target = this.targetNode.style.cursor;
  201. this.targetNode.style.cursor = curVal;
  202. },
  203. getCoordinates: function getCoordinates() {
  204. return this._getCords();
  205. }
  206. });
  207. return LassoSelectView;
  208. });
  209. //# sourceMappingURL=LassoSelectView.js.map