/*******************************************************************************
* Copyright (c) 2016 itemis AG and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Matthias Wienand (itemis AG) - initial API and implementation
*
*******************************************************************************/
package org.eclipse.gef.mvc.examples.logo.policies;
import org.eclipse.gef.fx.nodes.InfiniteCanvas;
import org.eclipse.gef.mvc.fx.policies.ViewportPolicy;
import org.eclipse.gef.mvc.fx.viewer.InfiniteCanvasViewer;
import javafx.geometry.Bounds;
public class ContentRestrictedChangeViewportPolicy extends ViewportPolicy {
@Override
protected void locallyExecuteOperation() {
// determine current translation
double tx = getChangeViewportOperation().getNewHorizontalScrollOffset();
double ty = getChangeViewportOperation().getNewVerticalScrollOffset();
// determine direction of change
double dx = tx - getChangeViewportOperation().getInitialHorizontalScrollOffset();
double dy = ty - getChangeViewportOperation().getInitialVerticalScrollOffset();
// determine scrollable bounds
InfiniteCanvasViewer viewer = (InfiniteCanvasViewer) getHost().getRoot().getViewer();
InfiniteCanvas canvas = viewer.getCanvas();
Bounds scrollableBounds = canvas.getScrollableBounds();
// compute content restricted translation range
// XXX: Scrolling is implemented by translating the scene graph node
// that holds all children. Therefore, scrolling to the right is
// actually moving this node to the left, and vice versa.
double contentRestrictedMinTranslateX = -scrollableBounds.getMinX();
double contentRestrictedMinTranslateY = -scrollableBounds.getMinY();
// XXX: The size of the canvas is the visible area which has to be
// subtracted from the scrollable bounds to yield the translation range.
double contentRestrictedMaxTranslateX = -(scrollableBounds.getMaxX() - canvas.getWidth());
double contentRestrictedMaxTranslateY = -(scrollableBounds.getMaxY() - canvas.getHeight());
// sort content restricted bounds numerically
if (contentRestrictedMinTranslateX > contentRestrictedMaxTranslateX) {
double tmp = contentRestrictedMinTranslateX;
contentRestrictedMinTranslateX = contentRestrictedMaxTranslateX;
contentRestrictedMaxTranslateX = tmp;
}
if (contentRestrictedMinTranslateY > contentRestrictedMaxTranslateY) {
double tmp = contentRestrictedMinTranslateY;
contentRestrictedMinTranslateY = contentRestrictedMaxTranslateY;
contentRestrictedMaxTranslateY = tmp;
}
// do not allow translation when the corresponding scrollbar is
// invisible, and otherwise restrict the translation values to the
// scrollable bounds
if (!canvas.getHorizontalScrollBar().isVisible()) {
tx = getChangeViewportOperation().getInitialHorizontalScrollOffset();
} else if (tx < contentRestrictedMinTranslateX || tx > contentRestrictedMaxTranslateX) {
// restrict to minimum/maximum depending on direction
if (dx < 0) {
tx = contentRestrictedMinTranslateX;
} else {
tx = contentRestrictedMaxTranslateX;
}
}
if (!canvas.getVerticalScrollBar().isVisible()) {
ty = getChangeViewportOperation().getInitialVerticalScrollOffset();
} else if (ty < contentRestrictedMinTranslateY || ty > contentRestrictedMaxTranslateY) {
// restrict to minimum/maximum depending on direction
if (dy < 0) {
ty = contentRestrictedMinTranslateY;
} else {
ty = contentRestrictedMaxTranslateY;
}
}
// change operation values
getChangeViewportOperation().setNewHorizontalScrollOffset(tx);
getChangeViewportOperation().setNewVerticalScrollOffset(ty);
// execute
super.locallyExecuteOperation();
}
}