You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by mc...@apache.org on 2019/04/12 19:27:42 UTC
[nifi] branch master updated: NIFI-4230 - Use a better default
location when pasting via keystokes and the original copied item is not
fully in view. - handle multi-select copy/paste better. - remove dimension
info from getOrigin function - handle pasting better when pasted items
should be centered and not offset from the original. - fixed strict mode
and removed console.logs - Fixing pasting logic when trying to center the
items on the canvas.
This is an automated email from the ASF dual-hosted git repository.
mcgilman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nifi.git
The following commit(s) were added to refs/heads/master by this push:
new b5ff622 NIFI-4230 - Use a better default location when pasting via keystokes and the original copied item is not fully in view. - handle multi-select copy/paste better. - remove dimension info from getOrigin function - handle pasting better when pasted items should be centered and not offset from the original. - fixed strict mode and removed console.logs - Fixing pasting logic when trying to center the items on the canvas.
b5ff622 is described below
commit b5ff62211808afbb427ece220e55ddfba048cf8a
Author: Rob Fellows <ro...@gmail.com>
AuthorDate: Thu Mar 21 09:24:14 2019 -0400
NIFI-4230 - Use a better default location when pasting via keystokes and the original copied item is not fully in view.
- handle multi-select copy/paste better.
- remove dimension info from getOrigin function
- handle pasting better when pasted items should be centered and not offset from the original.
- fixed strict mode and removed console.logs
- Fixing pasting logic when trying to center the items on the canvas.
This closes #3383
---
.../src/main/webapp/js/nf/canvas/nf-actions.js | 26 ++++-
.../main/webapp/js/nf/canvas/nf-canvas-utils.js | 124 ++++++++++++++++++++-
2 files changed, 144 insertions(+), 6 deletions(-)
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js
index bf32d5b..cb33ccc 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-actions.js
@@ -1722,12 +1722,14 @@
// determine the origin of the bounding box of the selection
var origin = nfCanvasUtils.getOrigin(selection);
+ var selectionDimensions = nfCanvasUtils.getSelectionBoundingClientRect(selection);
// copy the snippet details
var parentGroupId = nfCanvasUtils.getGroupId();
nfClipboard.copy({
snippet: nfSnippet.marshal(selection, parentGroupId),
- origin: origin
+ origin: origin,
+ dimensions: selectionDimensions
});
},
@@ -1771,12 +1773,28 @@
// determine the origin of the bounding box of the copy
var origin = pasteLocation;
var snippetOrigin = data['origin'];
+ var dimensions = data['dimensions'];
// determine the appropriate origin
if (!nfCommon.isDefinedAndNotNull(origin)) {
- snippetOrigin.x += 25;
- snippetOrigin.y += 25;
- origin = snippetOrigin;
+ // if the copied item(s) are from a different group or the origin item is not in the viewport, center the pasted item(s)
+ if (nfCanvasUtils.getGroupId() !== data['snippet'].parentGroupId || !nfCanvasUtils.isBoundingBoxInViewport(dimensions, false)) {
+ var scale = nfCanvasUtils.getCanvasScale();
+
+ // put it in the center of the screen
+ var center = nfCanvasUtils.getCenterForBoundingBox(dimensions);
+ var translate = nfCanvasUtils.getCanvasTranslate();
+ origin = {
+ x: center[0] - (translate[0] / scale),
+ y: center[1] - (translate[1] / scale)
+ };
+
+ } else {
+ // paste it just offset from the original
+ snippetOrigin.x += 25;
+ snippetOrigin.y += 25;
+ origin = snippetOrigin;
+ }
}
// copy the snippet to the new location
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-utils.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-utils.js
index b41cbfb..6d908d8 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-utils.js
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/nf/canvas/nf-canvas-utils.js
@@ -575,11 +575,12 @@
},
/**
- * Centers the specified bounding box.
+ * Gets the coordinates neccessary to center a bounding box on the screen.
*
* @param {type} boundingBox
+ * @returns {number[]}
*/
- centerBoundingBox: function (boundingBox) {
+ getCenterForBoundingBox: function (boundingBox) {
var scale = nfCanvas.View.getScale();
if (nfCommon.isDefinedAndNotNull(boundingBox.scale)) {
scale = boundingBox.scale;
@@ -592,6 +593,56 @@
// determine the center location for this component in canvas space
var center = [(screenWidth / 2) - (boundingBox.width / 2), (screenHeight / 2) - (boundingBox.height / 2)];
+ return center;
+ },
+
+ /**
+ * Determines if a bounding box is fully in the current viewable canvas area.
+ *
+ * @param {type} boundingBox Bounding box to check.
+ * @param {boolean} strict If true, the entire bounding box must be in the viewport.
+ * If false, only part of the bounding box must be in the viewport.
+ * @returns {boolean}
+ */
+ isBoundingBoxInViewport: function (boundingBox, strict) {
+ var scale = nfCanvas.View.getScale();
+ var translate = nfCanvas.View.getTranslate();
+ var offset = nfCanvas.CANVAS_OFFSET;
+
+ // get the canvas normalized width and height
+ var canvasContainer = $('#canvas-container');
+ var screenWidth = Math.floor(canvasContainer.width() / scale);
+ var screenHeight = Math.floor(canvasContainer.height() / scale);
+ var screenLeft = Math.ceil(-translate[0] / scale);
+ var screenTop = Math.ceil(-translate[1] / scale);
+ var screenRight = screenLeft + screenWidth;
+ var screenBottom = screenTop + screenHeight;
+
+ var left = Math.ceil(boundingBox.x);
+ var right = Math.floor(boundingBox.x + boundingBox.width);
+ var top = Math.ceil(boundingBox.y - (offset) / scale);
+ var bottom = Math.floor(boundingBox.y - (offset / scale) + boundingBox.height);
+
+ if (strict) {
+ return !(left < screenLeft || right > screenRight || top < screenTop || bottom > screenBottom);
+ } else {
+ return ((left > screenLeft && left < screenRight) || (right < screenRight && right > screenLeft)) &&
+ ((top > screenTop && top < screenBottom) || (bottom < screenBottom && bottom > screenTop));
+ }
+ },
+
+ /**
+ * Centers the specified bounding box.
+ *
+ * @param {type} boundingBox
+ */
+ centerBoundingBox: function (boundingBox) {
+ var scale = nfCanvas.View.getScale();
+ if (nfCommon.isDefinedAndNotNull(boundingBox.scale)) {
+ scale = boundingBox.scale;
+ }
+
+ var center = nfCanvasUtils.getCenterForBoundingBox(boundingBox);
// calculate the difference between the center point and the position of this component and convert to screen space
nfCanvas.View.transform([(center[0] - boundingBox.x) * scale, (center[1] - boundingBox.y) * scale], scale);
@@ -1764,6 +1815,75 @@
},
/**
+ * Get a BoundingClientRect, normalized to the canvas, that encompasses all nodes in a given selection.
+ *
+ * @param selection
+ * @returns {*} BoundingClientRect
+ */
+ getSelectionBoundingClientRect: function (selection) {
+ var scale = nfCanvas.View.getScale();
+ var translate = nfCanvas.View.getTranslate();
+
+ var initialBBox = {
+ x: Number.MAX_VALUE,
+ y: Number.MAX_VALUE,
+ right: Number.MIN_VALUE,
+ bottom: Number.MIN_VALUE,
+ translate: nfCanvas.View.getTranslate()
+ };
+
+ var bbox = selection.nodes().reduce(function (aggregateBBox, node) {
+ var rect = node.getBoundingClientRect();
+ aggregateBBox.x = Math.min(rect.x, aggregateBBox.x);
+ aggregateBBox.y = Math.min(rect.y, aggregateBBox.y);
+ aggregateBBox.right = Math.max(rect.right, aggregateBBox.right);
+ aggregateBBox.bottom = Math.max(rect.bottom, aggregateBBox.bottom);
+
+ return aggregateBBox;
+ }, initialBBox);
+
+ // normalize the bounding box with scale and translate
+ bbox.x = (bbox.x - translate[0]) / scale;
+ bbox.y = (bbox.y - translate[1]) / scale;
+ bbox.right = (bbox.right - translate[0]) / scale;
+ bbox.bottom = (bbox.bottom - translate[1]) / scale;
+
+ bbox.width = bbox.right - bbox.x;
+ bbox.height = bbox.bottom - bbox.y;
+ bbox.top = bbox.y;
+ bbox.left = bbox.x;
+
+ return bbox;
+ },
+
+ /**
+ * Applies a translation to BoundingClientRect.
+ *
+ * @param boundingClientRect
+ * @param translate
+ * @returns {{top: number, left: number, bottom: number, x: number, width: number, y: number, right: number, height: number}}
+ */
+ translateBoundingClientRect: function (boundingClientRect, translate) {
+ if (nfCommon.isUndefinedOrNull(translate)) {
+ if (nfCommon.isDefinedAndNotNull(boundingClientRect.translate)) {
+ translate = boundingClientRect.translate;
+ } else {
+ translate = nfCanvas.View.getTranslate();
+ }
+ }
+ return {
+ x: boundingClientRect.x - translate[0],
+ y: boundingClientRect.y - translate[1],
+ left: boundingClientRect.left - translate[0],
+ right: boundingClientRect.right - translate[0],
+ top: boundingClientRect.top - translate[1],
+ bottom: boundingClientRect.bottom - translate[1],
+ width: boundingClientRect.width,
+ height: boundingClientRect.height
+ }
+ },
+
+ /**
* Moves the specified components into the current parent group.
*
* @param {selection} components