constrain.js revision 0ce21a2762300a493f87331397ca2b814905718b
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney /**
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * The Drag & Drop Utility allows you to create a draggable interface efficiently, buffering you from browser-level abnormalities and enabling you to focus on the interesting logic surrounding your particular implementation. This component enables you to create a variety of standard draggable objects with just a few lines of code and then, using its extensive API, add your own specific implementation logic.
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @module dd
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @submodule dd-constrain
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney */
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney /**
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * Plugin for the dd-drag module to add the constraining methods to it. It supports constraining to a node or viewport. It supports tick based moves and XY axis constraints.
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @class DDConstrained
9831c611ec39b61dea834e7ac37564708865c6e6Luke Smith * @extends Base
8dd487c5a842e74ad5cb36d49493d0a0d552f8d3Jeff Conniff * @constructor
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @namespace Plugin
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney */
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney
ce93c9e30dd338180488beb781d0cb1b0473654aLuke Smith var DRAG_NODE = 'dragNode',
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney OFFSET_HEIGHT = 'offsetHeight',
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney OFFSET_WIDTH = 'offsetWidth',
6797a96aa17cfbc2eb9b3f90f564a29c01519324Satyen Desai HOST = 'host',
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney TICK_X_ARRAY = 'tickXArray',
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff TICK_Y_ARRAY = 'tickYArray',
9831c611ec39b61dea834e7ac37564708865c6e6Luke Smith DDM = Y.DD.DDM,
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith TOP = 'top',
132071043437e241d6e56b435e6ee010de2f3e9dJeff Conniff RIGHT = 'right',
8dd487c5a842e74ad5cb36d49493d0a0d552f8d3Jeff Conniff BOTTOM = 'bottom',
9c46bf9bc0ac9bab8d409ae4ab6d2a2ddc4dc55bJeff Conniff LEFT = 'left',
80ea28fae9dc032e5b99c726c41e492cd59bf49dJeff Conniff VIEW = 'view',
80ea28fae9dc032e5b99c726c41e492cd59bf49dJeff Conniff proto = null,
9c46bf9bc0ac9bab8d409ae4ab6d2a2ddc4dc55bJeff Conniff C = function(config) {
d909360e6d2b72521cc26a0cd458a68cb4337b66Jeff Conniff this._lazyAddAttrs = false;
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney C.superclass.constructor.apply(this, arguments);
6340fd3eeb615e0720d218535598b6627a3d4c71Jeff Conniff };
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff
6340fd3eeb615e0720d218535598b6627a3d4c71Jeff Conniff C.NAME = 'ddConstrained';
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff /**
6340fd3eeb615e0720d218535598b6627a3d4c71Jeff Conniff * @property NS
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @default con
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @readonly
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @protected
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @static
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description The Constrained instance will be placed on the Drag instance under the con namespace.
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @type {String}
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney */
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney C.NS = 'con';
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney C.ATTRS = {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney host: {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney },
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney /**
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @attribute stickX
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description Stick the drag movement to the X-Axis. Default: false
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @type Boolean
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney */
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney stickX: {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney value: false
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff },
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney /**
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @attribute stickY
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description Stick the drag movement to the Y-Axis
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @type Boolean
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff */
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney stickY: {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney value: false
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney },
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney /**
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @attribute tickX
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description The X tick offset the drag node should snap to on each drag move. False for no ticks. Default: false
dba22eabcfca7e9fe626abbad1494c3a0200dde0Matt Sweeney * @type Number/false
dba22eabcfca7e9fe626abbad1494c3a0200dde0Matt Sweeney */
dba22eabcfca7e9fe626abbad1494c3a0200dde0Matt Sweeney tickX: {
dba22eabcfca7e9fe626abbad1494c3a0200dde0Matt Sweeney value: false
132071043437e241d6e56b435e6ee010de2f3e9dJeff Conniff },
4fb6ac462f41bde792472a5c16609fafb26421e5Jeff Conniff /**
4fb6ac462f41bde792472a5c16609fafb26421e5Jeff Conniff * @attribute tickY
4fb6ac462f41bde792472a5c16609fafb26421e5Jeff Conniff * @description The Y tick offset the drag node should snap to on each drag move. False for no ticks. Default: false
4fb6ac462f41bde792472a5c16609fafb26421e5Jeff Conniff * @type Number/false
132071043437e241d6e56b435e6ee010de2f3e9dJeff Conniff */
132071043437e241d6e56b435e6ee010de2f3e9dJeff Conniff tickY: {
dba22eabcfca7e9fe626abbad1494c3a0200dde0Matt Sweeney value: false
ce93c9e30dd338180488beb781d0cb1b0473654aLuke Smith },
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney /**
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @attribute tickXArray
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description An array of page coordinates to use as X ticks for drag movement.
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @type Array
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney */
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney tickXArray: {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney value: false
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney },
ce93c9e30dd338180488beb781d0cb1b0473654aLuke Smith /**
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @attribute tickYArray
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description An array of page coordinates to use as Y ticks for drag movement.
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @type Array
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney */
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney tickYArray: {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney value: false
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney },
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney /**
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @attribute gutter
d40e32ef6c95cddf35e9cc056dfdd259ba314fa2Jeff Conniff * @description CSS style string for the gutter of a region (supports negative values): '5 0' (sets top and bottom to 5px, left and right to 0px), '1 2 3 4' (top 1px, right 2px, bottom 3px, left 4px)
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @type String
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney */
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney gutter: {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney value: '0',
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney setter: function(gutter) {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney return Y.DD.DDM.cssSizestoObject(gutter);
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney }
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff },
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff /**
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff * @attribute constrain
6340fd3eeb615e0720d218535598b6627a3d4c71Jeff Conniff * @description Will attempt to constrain the drag node to the boundaries. Arguments:<br>
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff * 'view': Contrain to Viewport<br>
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff * '#selector_string': Constrain to this node<br>
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff * '{Region Object}': An Object Literal containing a valid region (top, right, bottom, left) of page positions
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff * @type {String/Object/Node}
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff */
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff constrain: {
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff value: VIEW,
6340fd3eeb615e0720d218535598b6627a3d4c71Jeff Conniff setter: function(con) {
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff var node = Y.one(con);
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff if (node) {
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff con = node;
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff }
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff return con;
d6ac1282b7aebe50016ff2242315c34ac60422c8Jeff Conniff }
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney },
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney /**
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @deprecated
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @attribute constrain2region
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description An Object Literal containing a valid region (top, right, bottom, left) of page positions to constrain the drag node to.
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @type Object
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney */
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney constrain2region: {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney setter: function(r) {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney Y.log('constrain2region is deprecated use constrain: {Region}', 'warn', 'dd');
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney return this.set('constrain', r);
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney }
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney },
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney /**
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @deprecated
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff * @attribute constrain2node
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description Will attempt to constrain the drag node to the boundaries of this node.
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @type Object
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff */
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney constrain2node: {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney setter: function(n) {
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff Y.log('constrain2node is deprecated use constrain: NodeInstance', 'warn', 'dd');
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney return this.set('constrain', Y.one(n));
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney }
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney },
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney /**
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @deprecated
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @attribute constrain2view
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description Will attempt to constrain the drag node to the boundaries of the viewport region.
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @type Object
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney */
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney constrain2view: {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney setter: function(n) {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney Y.log('constrain2view is deprecated use constrain: "view"', 'warn', 'dd');
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney return this.set('constrain', VIEW);
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney }
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney },
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney /**
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @attribute cacheRegion
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description Should the region be cached for performace. Default: true
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @type Boolean
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney */
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney cacheRegion: {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney value: true
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney }
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff };
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney proto = {
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff initializer: function() {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney this.get(HOST).on('drag:start', Y.bind(this._handleStart, this));
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney this.get(HOST).after('drag:align', Y.bind(this.align, this));
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney },
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney /**
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @private
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff * @method _handleStart
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff * @description Fires on drag:start and clears the _regionCache
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff */
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney _handleStart: function() {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney this.resetCache();
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney },
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff /**
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff * @private
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff * @property _regionCache
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff * @description Store a cache of the region that we are constraining to
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff * @type Object
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff */
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff _regionCache: null,
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff /**
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff * @private
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff * @method _cacheRegion
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff * @description Get's the region and caches it, called from window.resize and when the cache is null
433c6e4d8b64100e84f0a4d37768706d5951994fJeff Conniff */
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney _cacheRegion: function() {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney this._regionCache = this.get('constrain').get('region');
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney },
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney /**
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @method resetCache
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description Reset the internal region cache.
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney */
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney resetCache: function() {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney this._regionCache = null;
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney },
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney /**
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @private
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @method _getConstraint
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description Standardizes the 'constraint' attribute
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney */
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney _getConstraint: function() {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney var con = this.get('constrain'),
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney g = this.get('gutter'),
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney region;
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney if (con) {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney if (con instanceof Y.Node) {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney if (!this._regionCache) {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney Y.on('resize', Y.bind(this._cacheRegion, this), Y.config.win);
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney this._cacheRegion();
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney }
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney region = Y.clone(this._regionCache);
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney if (!this.get('cacheRegion')) {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney this.resetCache();
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney }
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff } else if (Y.Lang.isObject(con)) {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney region = con;
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney }
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney }
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney if (!con || !region) {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney con = VIEW;
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney }
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney if (con === VIEW) {
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff region = this.get(HOST).get(DRAG_NODE).get('viewportRegion');
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney }
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney Y.each(g, function(i, n) {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney if ((n == RIGHT) || (n == BOTTOM)) {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney region[n] -= i;
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff } else {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney region[n] += i;
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney }
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney });
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney return region;
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney },
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney /**
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @method getRegion
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description Get the active region: viewport, node, custom region
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @param {Boolean} inc Include the node's height and width
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @return {Object}
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney */
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney getRegion: function(inc) {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney var r = {}, oh = null, ow = null,
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney host = this.get(HOST);
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney r = this._getConstraint();
719d5bf86fc9cfc087ec8bf8cc7e1ad78bbf9ccfJeff Conniff
719d5bf86fc9cfc087ec8bf8cc7e1ad78bbf9ccfJeff Conniff if (inc) {
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff oh = host.get(DRAG_NODE).get(OFFSET_HEIGHT);
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff ow = host.get(DRAG_NODE).get(OFFSET_WIDTH);
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff r[RIGHT] = r[RIGHT] - ow;
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney r[BOTTOM] = r[BOTTOM] - oh;
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney }
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney return r;
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney },
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff /**
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @private
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @method _checkRegion
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @description Check if xy is inside a given region, if not change to it be inside.
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @param {Array} _xy The XY to check if it's in the current region, if it isn't inside the region, it will reset the xy array to be inside the region.
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @return {Array} The new XY that is inside the region
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff */
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff _checkRegion: function(_xy) {
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff var oxy = _xy,
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff r = this.getRegion(),
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff host = this.get(HOST),
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff oh = host.get(DRAG_NODE).get(OFFSET_HEIGHT),
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff ow = host.get(DRAG_NODE).get(OFFSET_WIDTH);
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff if (oxy[1] > (r[BOTTOM] - oh)) {
719d5bf86fc9cfc087ec8bf8cc7e1ad78bbf9ccfJeff Conniff _xy[1] = (r[BOTTOM] - oh);
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff }
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff if (r[TOP] > oxy[1]) {
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff _xy[1] = r[TOP];
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff }
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff if (oxy[0] > (r[RIGHT] - ow)) {
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff _xy[0] = (r[RIGHT] - ow);
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff }
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff if (r[LEFT] > oxy[0]) {
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff _xy[0] = r[LEFT];
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff }
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff return _xy;
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff },
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff /**
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @method inRegion
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @description Checks if the XY passed or the dragNode is inside the active region.
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @param {Array} xy Optional XY to check, if not supplied this.get('dragNode').getXY() is used.
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @return {Boolean} True if the XY is inside the region, false otherwise.
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff */
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff inRegion: function(xy) {
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff xy = xy || this.get(HOST).get(DRAG_NODE).getXY();
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff var _xy = this._checkRegion([xy[0], xy[1]]),
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff inside = false;
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff if ((xy[0] === _xy[0]) && (xy[1] === _xy[1])) {
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff inside = true;
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff }
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff return inside;
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff },
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff /**
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @method align
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @description Modifies the Drag.actXY method from the after drag:align event. This is where the constraining happens.
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff */
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff align: function() {
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff var host = this.get(HOST),
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff _xy = host.actXY,
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff r = this.getRegion(true);
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff if (this.get('stickX')) {
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff _xy[1] = (host.startXY[1] - host.deltaXY[1]);
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff }
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff if (this.get('stickY')) {
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff _xy[0] = (host.startXY[0] - host.deltaXY[0]);
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff }
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff if (r) {
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff _xy = this._checkRegion(_xy);
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff }
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff _xy = this._checkTicks(_xy, r);
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff host.actXY = _xy;
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff },
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff /**
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @private
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @method _checkTicks
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @description This method delegates the proper helper method for tick calculations
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @param {Array} xy The XY coords for the Drag
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @param {Object} r The optional region that we are bound to.
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff * @return {Array} The calced XY coords
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff */
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff _checkTicks: function(xy, r) {
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff var host = this.get(HOST),
b4f14fb8425b05925652295a6e65a98b2448f70fJeff Conniff lx = (host.startXY[0] - host.deltaXY[0]),
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff ly = (host.startXY[1] - host.deltaXY[1]),
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff xt = this.get('tickX'),
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff yt = this.get('tickY');
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff if (xt && !this.get(TICK_X_ARRAY)) {
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff xy[0] = DDM._calcTicks(xy[0], lx, xt, r[LEFT], r[RIGHT]);
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff }
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff if (yt && !this.get(TICK_Y_ARRAY)) {
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff xy[1] = DDM._calcTicks(xy[1], ly, yt, r[TOP], r[BOTTOM]);
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff }
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff if (this.get(TICK_X_ARRAY)) {
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff xy[0] = DDM._calcTickArray(xy[0], this.get(TICK_X_ARRAY), r[LEFT], r[RIGHT]);
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff }
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff if (this.get(TICK_Y_ARRAY)) {
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff xy[1] = DDM._calcTickArray(xy[1], this.get(TICK_Y_ARRAY), r[TOP], r[BOTTOM]);
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff }
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff return xy;
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff }
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff };
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff Y.namespace('Plugin');
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff Y.extend(C, Y.Base, proto);
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff Y.Plugin.DDConstrained = C;
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff Y.mix(DDM, {
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff /**
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff * @for DDM
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff * @namespace DD
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff * @private
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff * @method _calcTicks
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff * @description Helper method to calculate the tick offsets for a given position
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff * @param {Number} pos The current X or Y position
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff * @param {Number} start The start X or Y position
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff * @param {Number} tick The X or Y tick increment
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff * @param {Number} off1 The min offset that we can't pass (region)
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff * @param {Number} off2 The max offset that we can't pass (region)
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff * @return {Number} The new position based on the tick calculation
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff */
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff _calcTicks: function(pos, start, tick, off1, off2) {
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff var ix = ((pos - start) / tick),
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff min = Math.floor(ix),
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff max = Math.ceil(ix);
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff if ((min !== 0) || (max !== 0)) {
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff if ((ix >= min) && (ix <= max)) {
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff pos = (start + (tick * min));
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff if (off1 && off2) {
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff if (pos < off1) {
d3b7b73e5ca50ba0821b439d4f9a12cfaaf38870Jeff Conniff pos = (start + (tick * (min + 1)));
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff }
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff if (pos > off2) {
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff pos = (start + (tick * (min - 1)));
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff }
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff }
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff }
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff }
132071043437e241d6e56b435e6ee010de2f3e9dJeff Conniff return pos;
132071043437e241d6e56b435e6ee010de2f3e9dJeff Conniff },
4fb6ac462f41bde792472a5c16609fafb26421e5Jeff Conniff /**
132071043437e241d6e56b435e6ee010de2f3e9dJeff Conniff * @for DDM
132071043437e241d6e56b435e6ee010de2f3e9dJeff Conniff * @namespace DD
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @private
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @method _calcTickArray
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney * @description This method is used with the tickXArray and tickYArray config options
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith * @param {Number} pos The current X or Y position
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith * @param {Number} ticks The array containing our custom tick positions.
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith * @param {Number} off1 The min offset that we can't pass (region)
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith * @param {Number} off2 The max offset that we can't pass (region)
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith * @return The tick position
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith */
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith _calcTickArray: function(pos, ticks, off1, off2) {
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith var i = 0, len = ticks.length, next = 0,
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith diff1, diff2, ret;
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith if (!ticks || (ticks.length === 0)) {
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith return pos;
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith } else if (ticks[0] >= pos) {
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith return ticks[0];
132071043437e241d6e56b435e6ee010de2f3e9dJeff Conniff } else {
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith for (i = 0; i < len; i++) {
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith next = (i + 1);
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney if (ticks[next] && ticks[next] >= pos) {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney diff1 = pos - ticks[i];
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney diff2 = ticks[next] - pos;
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith ret = (diff2 > diff1) ? ticks[i] : ticks[next];
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith if (off1 && off2) {
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith if (ret > off2) {
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith if (ticks[i]) {
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith ret = ticks[i];
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney } else {
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney ret = ticks[len - 1];
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney }
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney }
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith }
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith return ret;
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith }
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith
c2007624cced6305bb875ada9ffcb6a1797e7e4cLuke Smith }
57944bee374767ef401f984a0136afb3822f22f7Matt Sweeney return ticks[ticks.length - 1];
d40e32ef6c95cddf35e9cc056dfdd259ba314fa2Jeff Conniff }
d40e32ef6c95cddf35e9cc056dfdd259ba314fa2Jeff Conniff }
d40e32ef6c95cddf35e9cc056dfdd259ba314fa2Jeff Conniff });
d40e32ef6c95cddf35e9cc056dfdd259ba314fa2Jeff Conniff
07ad9ab2be0e01d9fe09926c37a65a867aa6f401Jeff Conniff
d40e32ef6c95cddf35e9cc056dfdd259ba314fa2Jeff Conniff