Commit 75809399 authored by Alexander Diewald's avatar Alexander Diewald
Browse files

- Improve move behaviour of groups of elements in the graphical editor (placement).

  - Get the number of moved (sub-)elements and store it in the extended metadata map of the moved elements.
  - Adjust the movement point calculation to the number of elements (als improve snap to grid).
refs 2751
parent 47347560
......@@ -20,7 +20,10 @@ package org.fortiss.tooling.base.ui.editpart;
import static org.fortiss.tooling.base.ui.utils.LayoutDataUIUtils.getNodeBounds;
import static org.fortiss.tooling.base.ui.utils.SnapToGridUtils.snapToGridAdapter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.conqat.ide.commons.ui.swt.FontUtils;
import org.eclipse.draw2d.ChopboxAnchor;
......@@ -34,7 +37,10 @@ import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.Request;
import org.eclipse.gef.RequestConstants;
import org.eclipse.gef.SnapToHelper;
import org.eclipse.gef.commands.Command;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Font;
......@@ -135,6 +141,42 @@ public abstract class ElementEditPartBase<T extends ILayoutedModelElement & INam
new DirectConnectionAndReconnectionEditPolicy());
}
/** {@inheritDoc} */
@Override
public Command getCommand(Request request) {
// We need to extract the number of moved elements to determine the correct move deltas in
// case the editor is at a non-one zoom level.
// The number of moved elements is passed using the extended metadata map.
if(REQ_MOVE.equals(request.getType())) {
List<EObject> filteredSelection = new ArrayList<>();
// Get the selected graphical elements and collect the corresponding model objects.
ISelection sel = getViewer().getSelection();
List<?> selList = ((StructuredSelection)sel).toList();
// TODO (#2779): Use the map method from the yet to come LambdaUtil class.
List<EObject> selList2 =
selList.stream().map(e -> ((EditPart)e).getModel()).map(EObject.class::cast)
.collect(Collectors.toList());
// Consider only elements that are direct children of the selected layer in the editor
// (other elements are also shown and can be selected). Hence, filter out these
// sub-child elements to determine the number of moved child elements.
List<EObject> selList3 = new ArrayList<>();
selList2.stream().forEach(e -> selList3.addAll(e.eContents()));
for(EObject eObj : selList2) {
if(!selList3.contains(eObj)) {
filteredSelection.add(eObj);
}
}
// Unchecked due to raw map.
@SuppressWarnings("unchecked") Map<String, Integer> extMetaData =
request.getExtendedData();
extMetaData.put("SELECTED_ELEM_NUM", filteredSelection.size());
}
return super.getCommand(request);
}
/** {@inheritDoc} */
@Override
public void performRequest(Request req) {
......
......@@ -26,6 +26,7 @@ import org.eclipse.gef.RootEditPart;
import org.eclipse.gef.editparts.ScalableFreeformRootEditPart;
import org.eclipse.gef.editparts.ScalableRootEditPart;
import org.eclipse.gef.requests.ChangeBoundsRequest;
import org.fortiss.tooling.base.layout.DefaultLayoutConstants;
import org.fortiss.tooling.base.utils.ZoomUtils;
/**
......@@ -38,6 +39,9 @@ import org.fortiss.tooling.base.utils.ZoomUtils;
*/
public class ZoomUIUtils {
/** Factor to align zoomed movements to 0.05 steps (==> avail. zoom factors). */
private static int ZOOM_ALIGN_FACTOR = 20;
/** Extracts the current zoom level from the given root edit part. */
public static double determineZoom(RootEditPart rootEditPart) {
if(rootEditPart instanceof ScalableRootEditPart) {
......@@ -57,8 +61,27 @@ public class ZoomUIUtils {
if(zoom <= 0 || zoom == 1) {
return;
}
Integer numElem = (Integer)request.getExtendedData().get("SELECTED_ELEM_NUM");
if(numElem == null) {
// Do not consider elements that are part of the parent pane here, e.g. Ports.
// They are irrelevant for the calculation of the scale factor and would cause "jumping"
// of the selected elements.
return;
}
if(numElem != 1) {
zoom = 1 - (1 - zoom) / numElem;
zoom = Math.floor(zoom * ZOOM_ALIGN_FACTOR) / ZOOM_ALIGN_FACTOR;
}
request.setMoveDelta(screenToInternalPoint(request.getMoveDelta(), zoom));
request.setSizeDelta(screenToInternalDimension(request.getSizeDelta(), zoom));
// Adjust to grid (snap).
Point reqPoint = request.getMoveDelta();
SnapToGridUtils.snapToGrid(reqPoint,
(int)Math.round(DefaultLayoutConstants.DEFAULT_GRID_SIZE * zoom));
}
/**
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment