diff --git a/plugins/org.eclipse.fordiac.ide.application/src/org/eclipse/fordiac/ide/application/editparts/FBNetworkRootEditPart.java b/plugins/org.eclipse.fordiac.ide.application/src/org/eclipse/fordiac/ide/application/editparts/FBNetworkRootEditPart.java index 71c07fe773..370276aebd 100644 --- a/plugins/org.eclipse.fordiac.ide.application/src/org/eclipse/fordiac/ide/application/editparts/FBNetworkRootEditPart.java +++ b/plugins/org.eclipse.fordiac.ide.application/src/org/eclipse/fordiac/ide/application/editparts/FBNetworkRootEditPart.java @@ -25,11 +25,13 @@ import org.eclipse.fordiac.ide.application.editors.NewInstanceDirectEditManager; import org.eclipse.fordiac.ide.gef.editparts.ZoomScalableFreeformRootEditPart; import org.eclipse.fordiac.ide.gef.tools.AdvancedMarqueeDragTracker; +import org.eclipse.fordiac.ide.gef.tools.FordiacViewportAutoexposeHelper; import org.eclipse.fordiac.ide.model.commands.create.AbstractCreateFBNetworkElementCommand; import org.eclipse.fordiac.ide.model.libraryElement.FBNetwork; import org.eclipse.fordiac.ide.model.libraryElement.FBNetworkElement; import org.eclipse.fordiac.ide.model.typelibrary.TypeEntry; import org.eclipse.fordiac.ide.model.typelibrary.TypeLibrary; +import org.eclipse.gef.AutoexposeHelper; import org.eclipse.gef.DragTracker; import org.eclipse.gef.EditPartViewer; import org.eclipse.gef.GraphicalEditPart; @@ -137,6 +139,9 @@ public static Point getInsertPos(final LocationRequest request, final EditPartVi @Override public T getAdapter(final Class adapter) { + if (adapter == AutoexposeHelper.class) { + return adapter.cast(new FordiacViewportAutoexposeHelper(this)); + } if (adapter == FBNetwork.class) { return adapter.cast(fbNetwork); } diff --git a/plugins/org.eclipse.fordiac.ide.gef/src/org/eclipse/fordiac/ide/gef/tools/FordiacViewportAutoexposeHelper.java b/plugins/org.eclipse.fordiac.ide.gef/src/org/eclipse/fordiac/ide/gef/tools/FordiacViewportAutoexposeHelper.java new file mode 100644 index 0000000000..266f01b0d7 --- /dev/null +++ b/plugins/org.eclipse.fordiac.ide.gef/src/org/eclipse/fordiac/ide/gef/tools/FordiacViewportAutoexposeHelper.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2024 Martin Erich Jobst + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Martin Jobst - initial API and implementation and/or initial documentation + *******************************************************************************/ +package org.eclipse.fordiac.ide.gef.tools; + +import org.eclipse.draw2d.PositionConstants; +import org.eclipse.draw2d.Viewport; +import org.eclipse.draw2d.geometry.Insets; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; +import org.eclipse.gef.GraphicalEditPart; +import org.eclipse.gef.editparts.ViewportAutoexposeHelper; + +public class FordiacViewportAutoexposeHelper extends ViewportAutoexposeHelper { + + private static final Insets DEFAULT_EXPOSE_THRESHOLD = new Insets(100); + + private long lastStepTime = 0; + + private final Insets threshold; + + public FordiacViewportAutoexposeHelper(final GraphicalEditPart owner) { + this(owner, DEFAULT_EXPOSE_THRESHOLD); + } + + public FordiacViewportAutoexposeHelper(final GraphicalEditPart owner, final Insets threshold) { + super(owner, threshold); + this.threshold = threshold; + } + + @Override + public boolean step(final Point where) { + final Viewport port = findViewport(owner); + + final Rectangle rect = Rectangle.SINGLETON; + port.getClientArea(rect); + port.translateToParent(rect); + port.translateToAbsolute(rect); + if (!rect.contains(where)) { + return false; + } + + rect.shrink(threshold); + + if (rect.contains(where)) { + return false; + } + + if (lastStepTime == 0) { + lastStepTime = System.currentTimeMillis(); + } + + final long difference = System.currentTimeMillis() - lastStepTime; + + if (difference < 0) { + return true; + } + + lastStepTime = System.currentTimeMillis(); + + final int region = rect.getPosition(where); + final Point loc = port.getViewLocation(); + + if ((region & PositionConstants.SOUTH) != 0) { + loc.y += (int) difference * (where.y() - rect.bottom()) / threshold.bottom; + } else if ((region & PositionConstants.NORTH) != 0) { + loc.y += (int) difference * (where.y() - rect.top()) / threshold.top; + } + + if ((region & PositionConstants.EAST) != 0) { + loc.x += (int) difference * (where.x() - rect.right()) / threshold.right; + } else if ((region & PositionConstants.WEST) != 0) { + loc.x += (int) difference * (where.x() - rect.left()) / threshold.left; + } + + port.setViewLocation(loc); + return true; + } +}