123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788 |
- 'use strict';
- /**
- * Licensed Materials - Property of IBM
- * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2013, 2020
- * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
- */
- define(['./LayoutBaseView', 'jquery', 'underscore', '../../../../lib/@waca/core-client/js/core-client/utils/Deferred', '../../LayoutHelper', '../../../util/PxPercentUtil', '../../../glass/util/InstrumentationUtil'], function (BaseLayout, $, _, Deferred, LayoutHelper, PxPercentUtil, InstrumentationUtil) {
- var PageLayout = null;
- var WIDGET_PADDING = 5;
- PageLayout = BaseLayout.extend({
- init: function init(options) {
- PageLayout.inherited('init', this, arguments);
- if (this.layoutController.topLayoutModel) {
- this.layoutController.topLayoutModel.on('change:showGrid', this.renderGrid, this);
- this.layoutController.topLayoutModel.on('change:fitPage', this.renderGrid, this);
- this.layoutController.topLayoutModel.on('change:pageSize', this.onPageSize, this);
- }
- this.services = options.services;
- this._templateHelper = options.templateHelper; // Optional
- this.whenIsReadyDfd = new Deferred();
- this.specializeConsumeView(['setPreferredLocation']);
- this._initialize();
- },
- createDropZone: function createDropZone() {
- var _this = this;
- this._dropTarget = this._dndManager.addDropTarget(this.domNode, {
- accepts: this.accepts.bind(this),
- onDrop: this.onDrop.bind(this),
- onDragLeave: this.onDragLeave.bind(this),
- onDragEnd: this.onDragEnd.bind(this),
- onDragMove: this.onDragMove.bind(this),
- priority: -100 /* Indicate that any other drop zone takes priority */
- , info: function info(domNode, event) {
- return _this._getCoordsRelativeToTarget(domNode, event);
- },
- type: 'dropOnCanvas'
- });
- this._dropHandler = this._dndManager.registerDropHandler({
- accepts: function accepts(dragPayload, dropPayload) {
- return dragPayload.type.match(/content\..*/) && dropPayload.type === 'dropOnCanvas';
- },
- onDrop: function onDrop(dragPayload, dropPayload) {
- _this.onContentDrop(dragPayload, dropPayload);
- }
- });
- },
- _getCoordsRelativeToTarget: function _getCoordsRelativeToTarget(domNode, event) {
- var offset = $(domNode).offset();
- return {
- top: Math.round(event.pageY - offset.top + domNode.scrollTop),
- left: Math.round(event.pageX - offset.left + domNode.scrollLeft)
- };
- },
- onContentDrop: function onContentDrop(dragPayload, dropPayload) {
- var content = JSON.parse(JSON.stringify(dragPayload.data));
- var specStyle = content.spec.style || {};
- if (dropPayload && dropPayload.info) {
- var style = {
- width: specStyle.width,
- height: specStyle.height,
- top: dropPayload.info.top,
- left: dropPayload.info.left
- };
- this._stylePxToInt(style);
- this._setStyleWithinBounds(style);
- LayoutHelper.styleIntToPx(style);
- specStyle.width = style.width;
- specStyle.height = style.height;
- specStyle.left = style.left;
- specStyle.top = style.top;
- content.spec.style = specStyle;
- var canvas = this.dashboardApi.getFeature('Canvas');
- return canvas.addContent(content);
- }
- this.clearDragState();
- },
- onShow: function onShow() {
- PageLayout.inherited('onShow', this, arguments);
- this.renderGrid();
- },
- whenIsReady: function whenIsReady() {
- return this.whenIsReadyDfd.promise;
- },
- destroy: function destroy() {
- if (this._dropTarget) {
- this._dropTarget.remove();
- this._dropTarget = null;
- }
- if (this._dropHandler) {
- this._dropHandler.deregister();
- this._dropHandler = null;
- }
- this._dndManager = null;
- if ($.glassdnd && $.glassdnd.cancelDroppable) {
- $.glassdnd.cancelDroppable(this.$el);
- }
- this.$el.find('.absoluteLayoutGrid').remove();
- this.layoutController.topLayoutModel.off('change:showGrid', this.renderGrid, this);
- this.layoutController.topLayoutModel.off('change:pageSize', this.onPageSize, this);
- PageLayout.inherited('destroy', this, arguments);
- },
- removeChild: function removeChild() {
- PageLayout.inherited('removeChild', this, arguments);
- },
- _initialize: function _initialize() {
- this._dndManager = this.dashboardApi.getFeature('DashboardDnd.internal');
- this.whenIsReadyDfd.resolve();
- this.createDropZone();
- },
- _getDragPositionRelativeToTarget: function _getDragPositionRelativeToTarget(dragObject, target) {
- var offset = $(target).offset();
- return {
- top: Math.round(dragObject.position.y - offset.top + target.scrollTop),
- left: Math.round(dragObject.position.x - offset.left + target.scrollLeft)
- };
- },
- _getDragBoxForNewDrop: function _getDragBoxForNewDrop(dragObject, target) {
- var size = this._getDragObjectDimensions(dragObject);
- var coords = this._getDragPositionRelativeToTarget(dragObject, target);
- var dragBox = {
- top: coords.top,
- left: coords.left,
- ids: []
- };
- dragBox.right = dragBox.left + parseInt(size.width, 10);
- dragBox.bottom = dragBox.top + parseInt(size.height, 10);
- dragBox.center_x = (dragBox.left + dragBox.right) / 2;
- dragBox.center_y = (dragBox.top + dragBox.bottom) / 2;
- return dragBox;
- },
- /**
- * Get the drag object dimensions. We use the layout/style information if avaliable. If not, we use the drag avatar.
- */
- _getDragObjectDimensions: function _getDragObjectDimensions(dragObject) {
- var style = dragObject.data.layoutProperties && dragObject.data.layoutProperties.style || {};
- var $avatar = $(dragObject.avatar);
- if ($avatar.length === 0) {
- $avatar = $('.avatar');
- }
- return {
- width: style.width || $avatar.width() || '10px', //If we can't find anything to give a size, default to a 10*10 box
- height: style.height || $avatar.height() || '10px'
- };
- },
- _getDragBox: function _getDragBox(nodeInfoList) {
- var dragBox = nodeInfoList.reduce(function (box, current) {
- var $n = $(current.node),
- top,
- left,
- bottom,
- right;
- if (current.dropPosition) {
- top = current.dropPosition.y;
- left = current.dropPosition.x;
- bottom = top + $n.outerHeight();
- right = left + $n.outerWidth();
- } else {
- //If no dropPosition is present, don't affect the dragBox. This happens for group members, for which we can't currently scroll the canvas without disconnecting the widget and mouse.
- top = Infinity;
- left = Infinity;
- bottom = 0;
- right = 0;
- }
- box.top = Math.min(box.top, top);
- box.left = Math.min(box.left, left);
- box.bottom = Math.max(box.bottom, bottom);
- box.right = Math.max(box.right, right);
- box.ids.push(current.node.id);
- return box;
- }, {
- top: Infinity,
- left: Infinity,
- bottom: 0,
- right: 0,
- ids: []
- });
- dragBox.center_x = (dragBox.left + dragBox.right) / 2;
- dragBox.center_y = (dragBox.top + dragBox.bottom) / 2;
- return dragBox;
- },
- /**
- * Called by the DnD manager to check if this drop zone accept the dragged object
- * We only accept object with type widget, pin and groupContent
- * @returns {Boolean}
- */
- accepts: function accepts(dragObject) {
- var canvasDnD = this.dashboardApi.getFeature('CanvasDnD');
- return canvasDnD.accepts(dragObject, {
- fromCanvas: true
- });
- },
- /**
- * Called by the DnD manager when we move inside the drop zone (only if the drop zone accepts the object)
- * @param dragBox {object} A drag-position object with left,right,top,bottom and center_x, center_y.
- *
- */
- onDragMove: function onDragMove(dragObject, target) {
- this.$el.addClass('layoutDragInProgress');
- var nodeInfoList = dragObject.data && dragObject.data.nodeInfoList;
- if (nodeInfoList && nodeInfoList.length) {
- dragObject.dragBox = this._getDragBox(nodeInfoList);
- } else {
- dragObject.dragBox = this._getDragBoxForNewDrop(dragObject, target);
- }
- this.adjustScrollPosition(dragObject);
- },
- _moveDrop: function _moveDrop(dragObject) {
- var positionUpdateArray = [],
- nodeInfo,
- positionInfo;
- var i = 0;
- for (var iLen = dragObject.data.nodeInfoList.length; i < iLen; i++) {
- nodeInfo = dragObject.data.nodeInfoList[i];
- positionInfo = this.getWidgetPositionUpdate(nodeInfo);
- if (positionInfo) {
- positionUpdateArray.push(positionInfo);
- }
- }
- var transactionApi = this.dashboardApi.getFeature('Transaction');
- var transactionToken = transactionApi.startTransaction();
- var nodeIds = positionUpdateArray.map(function (update) {
- return update.id;
- });
- var insertBeforeMap = {};
- _.reduce(positionUpdateArray, function (oMap, item) {
- if (item.insertBefore) {
- oMap[item.id] = item.insertBefore;
- }
- return oMap;
- }, insertBeforeMap);
- this.dashboardApi.getCanvas().moveContent(this.model.id, nodeIds, transactionToken, insertBeforeMap);
- this.updateModel(positionUpdateArray, transactionToken);
- transactionApi.endTransaction(transactionToken);
- },
- _newDrop: function _newDrop(dragObject, target, isTrackAction) {
- var _this2 = this;
- var layoutProperties = dragObject.data.layoutProperties || {};
- var offset = $(target).offset();
- if (target && offset) {
- return this._getModelToAddFromDragObject(dragObject).then(function (newModel) {
- if (newModel) {
- if (!layoutProperties.style) {
- layoutProperties.style = {};
- }
- var coords = _this2._getDragPositionRelativeToTarget(dragObject, target);
- var style = {
- width: layoutProperties.style.width,
- height: layoutProperties.style.height,
- top: coords.top,
- left: coords.left
- };
- _this2._stylePxToInt(style);
- _this2._setStyleWithinBounds(style);
- LayoutHelper.styleIntToPx(style);
- layoutProperties.style.width = style.width;
- layoutProperties.style.height = style.height;
- layoutProperties.style.left = style.left;
- layoutProperties.style.top = style.top;
- var widgetSpec = {
- parentId: _this2.id,
- model: newModel,
- layoutProperties: layoutProperties
- };
- if (isTrackAction) {
- InstrumentationUtil.trackWidget('created', _this2.dashboardApi, widgetSpec.model);
- }
- _this2._addWidget(widgetSpec, dragObject.isTouch);
- }
- });
- } else {
- return Promise.resolve();
- }
- },
- /**
- * A helper function handles pin dropping.
- * @param {object} dragObject - The dragObject to process
- */
- _onPinDrop: function _onPinDrop(dragObject) {
- var pinSpec = dragObject.data.pinSpec;
- var isTouch = dragObject.isTouch;
- var x = dragObject.position.x;
- var y = dragObject.position.y;
- // pin drop absolute location
- var top = Math.round(y - this.$el.offset().top) + 'px';
- var left = Math.round(x - this.$el.offset().left) + 'px';
- // we only need to consider gemini widget
- if (pinSpec.contentType === 'boardFragment') {
- // set absolute drop position back into the layout for top-left corner.
- // height width retained from original widget, this could be absolute
- // or a percentage if it came from a template. %age retains original
- // dimensions still
- if (!pinSpec.content.layout.style) {
- pinSpec.content.layout.style = {};
- }
- pinSpec.content.layout.style.top = top;
- pinSpec.content.layout.style.left = left;
- // If our pinSpec is too big for the content box, shrink and center it to fit. Only do this for pan-and-zoom.
- this._resizeToFitBoundaries(this.consumeView.getMaximumHeight(), this.consumeView.getMaximumWidth(), pinSpec.content.layout.style);
- }
- pinSpec.parentId = this.id;
- this._processWidgetSpecForPin(pinSpec, isTouch);
- },
- /** Resize the top, left, width & height of style such that they fit within the specified maxHeight and maxWidth,
- * maintaining their original aspect ratio.
- * @param maxHeight - maximum height of the layout specified in style
- * @param maxWidth - maximum width of the layout specified in style
- * @param style - expected to have height and width properties to compare with maxHeight and maxWidth. Will be resized to fit.
- */
- _resizeToFitBoundaries: function _resizeToFitBoundaries(maxHeight, maxWidth, style) {
- var width = parseInt(style.width, 10);
- var dWidth = maxWidth / width;
- var height = parseInt(style.height, 10);
- var dHeight = maxHeight / height;
- if (dWidth < 1 || dHeight < 1) {
- var dMultiple = Math.min(dWidth, dHeight);
- style.height = Math.round(height * dMultiple) + 'px';
- style.width = Math.round(width * dMultiple) + 'px';
- style.left = Math.round((maxWidth - Math.round(width * dMultiple)) / 2) + 'px';
- style.top = Math.round((maxHeight - Math.round(height * dMultiple)) / 2) + 'px';
- }
- },
- /**
- * Called by the drag&drop manager when a drop happens
- *
- * @param dragObject
- * @param targetNode
- */
- onDrop: function onDrop(dragObject, targetNode) {
- var _this3 = this;
- var promise = void 0;
- if (!dragObject.data && !targetNode) {
- promise = this._newDrop(dragObject.originalEvent, dragObject.targetNode);
- } else if (dragObject.data.operation === 'move') {
- promise = Promise.resolve(this._moveDrop(dragObject));
- } else if (dragObject.type === 'pin' && dragObject.data.operation === 'new') {
- //calls _onPinDrop when the dragObject with type pin
- promise = Promise.resolve(this._onPinDrop(dragObject));
- } else {
- promise = this._newDrop(dragObject, targetNode, /*isTrackAction*/true);
- }
- return promise.then(function () {
- return _this3.clearDragState();
- });
- },
- onDragLeave: function onDragLeave() {
- this.clearDragState(true);
- },
- onDragEnd: function onDragEnd() {
- this.clearDragState();
- this.previousDragBox = null;
- },
- clearDragState: function clearDragState() {
- this.$el.removeClass('layoutDragInProgress');
- },
- _changePercentModelToPixel: function _changePercentModelToPixel(style) {
- var $referenceView = this.$el;
- // this view could be hidden, so find a view that isn't hidden.
- if (!$referenceView.is(':visible')) {
- $referenceView = $(this.layoutController.getLastVisiblePage());
- }
- var referenceViewSize = {
- width: $referenceView.width(),
- height: $referenceView.height()
- };
- PxPercentUtil.changePercentPropertiesToPixel(style, referenceViewSize);
- },
- /**
- * Set the preferred layout location in the layout properties
- *
- * @param options
- * options.layoutProperties
- * options.parentId
- */
- setPreferredLocation: function setPreferredLocation(options) {
- var locationSet = false;
- if (this._templateHelper && !options.layoutProperties.style) {
- locationSet = this._templateHelper.setPreferredLocation(options);
- }
- if (!locationSet) {
- var properties = options.layoutProperties;
- if (!properties.style) {
- properties.style = {};
- }
- // get the dimensions of the widget being added
- var size = {
- width: properties.style.width || '300',
- height: properties.style.height || '300'
- };
- if (size.width.indexOf('%') !== -1 || size.height.indexOf('%') !== -1) {
- this._changePercentModelToPixel(size);
- }
- var width = parseInt(size.width, 10);
- var height = parseInt(size.height, 10);
- var location = !properties.style.top && !properties.style.left ? this.findAvailableSpace({
- width: width,
- height: height
- }) : null;
- if (location) {
- properties.style.top = location.top + 'px';
- properties.style.left = location.left + 'px';
- properties.style.width = properties.style.width || (location.width || width) + 'px';
- properties.style.height = properties.style.height || (location.height || height) + 'px';
- }
- // update the parent id
- options.parentId = this.model.id;
- }
- },
- getWidgetContainerNode: function getWidgetContainerNode() {
- return this.domNode;
- },
- /**
- * Find the location of the available space that fits the given dimensions
- *
- * 1- Sort the list of existing rectangles from left to right and from top to bottom using the center of the box.
- * 2- for each rectangle in the list do the following:
- * - find if there is available space that is adjacent to the bottom border
- *
- *
- * @param dimensions - dimensions that we are trying to find space for
- *
- * dimensions.width
- * dimensions.height
- *
- * @returns location - object that contains the top and left positions
- *
- */
- findAvailableSpace: function findAvailableSpace(dimensions) {
- // Get the scan options that will be used as input to scan for available space
- var usedSpaceRectArray = this.getChildrenRectList();
- // sort the rectangle from left to right and from top to bottom ( using the bottom border as the reference point).
- // This is the order that we use to try to find an available position
- var sortedUsedSpace = usedSpaceRectArray.slice(0).sort(function (a, b) {
- return a.height - b.height === 0 ? a.top - b.top === 0 ? a.left - b.left : a.top - b.top : a.height - b.height;
- });
- var i, iLen, rect;
- var coords = {
- top: 0,
- left: 0
- };
- for (i = 0, iLen = sortedUsedSpace.length; i < iLen; i++) {
- rect = sortedUsedSpace[i];
- coords = this.findSpaceAdjacentToBottomBorder(rect, dimensions, usedSpaceRectArray);
- if (coords) {
- break;
- }
- }
- var style = {
- width: dimensions.width,
- height: dimensions.height,
- top: coords.top,
- left: coords.left
- };
- this._setStyleWithinBounds(style);
- coords.top = style.top;
- coords.left = style.left;
- coords.width = style.width;
- coords.height = style.height;
- return coords;
- },
- /**
- * Check that widget style does not fall outside max bounds.
- * Updates the style to fit within bounds
- * Style should be unitless
- *
- * @param style
- */
- _setStyleWithinBounds: function _setStyleWithinBounds(style) {
- // will return Infinity if scrollDrop is supported
- var maxWidth = this.consumeView.getMaximumWidth();
- var maxHeight = this.consumeView.getMaximumHeight();
- if (isFinite(maxHeight) && isFinite(maxWidth)) {
- // widgets that are larger than layout will be fit to max size, maintaining ratio
- this._resizeToFitBoundaries(maxHeight, maxWidth, style);
- // convert to integer values for rest of operations
- this._stylePxToInt(style);
- // widgets with unknown width & height will occupy relative % of layout size
- if (!style.width && !style.height) {
- if (maxHeight > maxWidth) {
- style.width = Math.floor(maxWidth * 0.5);
- style.height = Math.floor(style.width * 3 / 4);
- } else {
- style.height = Math.floor(maxHeight * 0.5);
- style.width = Math.floor(style.height * 4 / 3);
- }
- }
- this.moveToFitBoundaries(maxHeight, maxWidth, style);
- }
- },
- _stylePxToInt: function _stylePxToInt(style) {
- for (var key in style) {
- if (style.hasOwnProperty(key)) {
- var value = style[key];
- if (value) {
- style[key] = parseInt(value, 10);
- }
- }
- }
- },
- /**
- * Find a space that is adjacent to the bottom border of a given rectangle where the space is bigger or equal to the given dimensions
- *
- *
- * @param topRect
- * @param dimensions
- * @param rectList
- * @returns
- */
- findSpaceAdjacentToBottomBorder: function findSpaceAdjacentToBottomBorder(topRect, dimensions, rectList) {
- // Find all the rectangles below the current rectangle that might intersect with the rectangle we are trying to add.
- var list = _.filter(rectList, function (rect) {
- return rect !== topRect && topRect.top + topRect.height < rect.top + rect.height && topRect.top + topRect.height + dimensions.height + WIDGET_PADDING > rect.top && rect.left <= topRect.left + topRect.width + dimensions.width + WIDGET_PADDING && rect.left + rect.width >= topRect.left - dimensions.width;
- });
- var coords;
- if (list.length === 0) {
- coords = {
- top: topRect.top + topRect.height + WIDGET_PADDING,
- left: topRect.left
- };
- } else {
- coords = this.findSpaceBetweenRectangles(topRect, list, dimensions);
- }
- return coords;
- },
- /**
- * Find a space that fits the given dimension by scanning between the rectangles in the list
- *
- * @param topRect - top boundary rectangle
- * @param list - list if rectangle to scan
- * @param dimensions - dimensions of the new rectangle we are trying to find
- * @param padding - padding used between rectangles
- * @returns
- */
- findSpaceBetweenRectangles: function findSpaceBetweenRectangles(topRect, list, dimensions) {
- var width = dimensions.width + WIDGET_PADDING;
- list.sort(function (a, b) {
- return a.left - b.left;
- });
- // If there is space before the first rectangle, then we insert before
- var top = topRect.top + topRect.height + WIDGET_PADDING;
- var first = list[0];
- if (first.left > topRect.left && first.left >= width && first.left - width > topRect.left - width) {
- return {
- top: top,
- left: Math.min(topRect.left, first.left - width)
- };
- }
- // Scan if there is space after each rectangle.
- var maxWidth = $(this.getWidgetContainerNode()).width();
- var rect, next;
- for (var i = 0; i < list.length; i++) {
- rect = list[i];
- next = list[i + 1];
- if (next && rect.left + rect.width > next.left + next.width) {
- // the next rectangle is contained within the current one. Throw it away and replace with the current rectangle.
- list[i + 1] = rect;
- } else {
- var rectLeft = next ? next.left : maxWidth;
- if (rect.left + rect.width + width <= rectLeft && topRect.left + topRect.width + width > rect.left + rect.width + width) {
- return {
- top: top,
- left: rect.left + rect.width + WIDGET_PADDING
- };
- }
- }
- }
- return null;
- },
- /**
- * Get the list of rectangle information for every child of this layout
- *
- * @returns {Array}
- */
- getChildrenRectList: function getChildrenRectList() {
- var usedSpaceArray = [];
- // Virtual boxes at the top and left of the page to force adding widgets at a certain padding
- usedSpaceArray.push({
- top: 0,
- left: 0,
- height: this.getMinimumTop() - WIDGET_PADDING,
- width: Math.round($(this.getWidgetContainerNode()).width())
- });
- usedSpaceArray.push({
- top: 0,
- left: 0,
- height: Math.round($(this.getWidgetContainerNode()).height()),
- width: this.getMinimumLeft() - WIDGET_PADDING
- });
- var children = $(this.getWidgetContainerNode()).children().not('.relativeLayoutGrid, .absoluteLayoutGrid, .pagetemplateIndicator, .pagetemplateDropZone, .sizeDashboardIndicatorContainer');
- var i, iLen;
- for (i = 0, iLen = children.length; i < iLen; i++) {
- var $child = $(children[i]);
- usedSpaceArray.push({
- top: $child[0].offsetTop,
- left: $child[0].offsetLeft,
- height: $child.outerHeight(),
- width: $child.outerWidth()
- });
- }
- return usedSpaceArray;
- },
- adjustScrollPosition: function adjustScrollPosition(dragObject) {
- var dragBox = dragObject.dragBox;
- var scrollInfo = this.getScrollInfo(dragObject);
- this.scrollToDragBox(dragBox, scrollInfo);
- },
- getScrollInfo: function getScrollInfo(dragObject) {
- var dragBox = dragObject.dragBox;
- var $node = this.getScrollAreaNode();
- var scrollInfo = {
- h: $node.height(),
- w: $node.width(),
- scrollTop: $node.scrollTop(),
- scrollLeft: $node.scrollLeft(),
- $node: $node,
- direction: []
- };
- if (this.previousDragBox) {
- if (dragBox.left !== this.previousDragBox.left) {
- scrollInfo.direction[dragBox.left - this.previousDragBox.left > 0 ? 'right' : 'left'] = true;
- }
- if (dragBox.top !== this.previousDragBox.top) {
- scrollInfo.direction[dragBox.top - this.previousDragBox.top > 0 ? 'bottom' : 'top'] = true;
- }
- }
- this.previousDragBox = dragBox;
- return scrollInfo;
- },
- getScrollAreaNode: function getScrollAreaNode() {
- var $parents = this.$el.parents('.page');
- var $el = this.$el;
- var index = 0;
- while ($el && $el.length && $el.css('overflow') !== 'auto') {
- $el = $parents.eq(index);
- index++;
- }
- if ($el.length === 0) {
- $el = this.$el;
- }
- return $el;
- },
- scrollToDragBox: function scrollToDragBox(dragBox, scrollInfo) {
- var SCROLL_INCREMENT = 16;
- var DRAG_EDGE_BUFFER_SIZE = 2; //Size of a buffer to add to the top & left checks due to varying mouse position. This will only be called as long as the mouse is over the canvas, and when inserting a widget, the mouse cursor is just outside the top-left corner making checks for scrolling up and left problematic.
- if (dragBox.bottom > scrollInfo.scrollTop + scrollInfo.h && scrollInfo.direction.bottom) {
- scrollInfo.$node.scrollTop(scrollInfo.scrollTop + SCROLL_INCREMENT);
- } else if (scrollInfo.scrollTop > dragBox.top - DRAG_EDGE_BUFFER_SIZE && scrollInfo.direction.top) {
- scrollInfo.$node.scrollTop(scrollInfo.scrollTop - SCROLL_INCREMENT);
- }
- if (dragBox.right > scrollInfo.scrollLeft + scrollInfo.w && scrollInfo.direction.right) {
- scrollInfo.$node.scrollLeft(scrollInfo.scrollLeft + SCROLL_INCREMENT);
- } else if (scrollInfo.scrollLeft > dragBox.left - DRAG_EDGE_BUFFER_SIZE && scrollInfo.direction.left) {
- scrollInfo.$node.scrollLeft(scrollInfo.scrollLeft - SCROLL_INCREMENT);
- }
- },
- renderGrid: function renderGrid() {
- var showGridProp = this.model.getValueFromSelfOrParent('showGrid');
- var showGrid = showGridProp === undefined ? false : showGridProp;
- var layoutPositioning = this.model.getValueFromSelfOrParent('layoutPositioning');
- if (showGrid && layoutPositioning === 'absolute') {
- if (this.$el.hasClass('gridCapable')) {
- this.$el.find('.absoluteLayoutGrid').remove();
- this.$el.prepend('<div class=absoluteLayoutGrid></div>');
- }
- } else {
- this.$el.find('.absoluteLayoutGrid').remove();
- }
- },
- onResize: function onResize() {
- PageLayout.inherited('onResize', this, arguments);
- this.renderGrid();
- },
- onPageSize: function onPageSize() {
- this.renderGrid();
- }
- });
- return PageLayout;
- });
- //# sourceMappingURL=Absolute.js.map
|