package org.archstudio.bna.logics.editing;
import org.archstudio.bna.IBNAView;
import org.archstudio.bna.IBNAWorld;
import org.archstudio.bna.IThing;
import org.archstudio.bna.constants.KeyType;
import org.archstudio.bna.facets.IHasMutableReferencePoint;
import org.archstudio.bna.facets.IHasReferencePoint;
import org.archstudio.bna.logics.AbstractThingLogic;
import org.archstudio.bna.ui.IBNAAllEventsListener2;
import org.archstudio.bna.ui.IBNAKeyListener2;
import org.archstudio.bna.utils.BNAUtils;
import org.archstudio.bna.utils.GridUtils;
import org.archstudio.bna.utils.UserEditableUtils;
import org.archstudio.swtutils.constants.Orientation;
import org.archstudio.sysutils.Finally;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.graphics.Point;
public class KeyNudgerLogic extends AbstractThingLogic implements IBNAKeyListener2, IBNAAllEventsListener2 {
public KeyNudgerLogic(IBNAWorld world) {
super(world);
}
@Override
public void keyPressed(IBNAView view, KeyType type, KeyEvent e) {
BNAUtils.checkLock();
if (e.keyCode == SWT.ARROW_LEFT || e.keyCode == SWT.ARROW_UP || e.keyCode == SWT.ARROW_DOWN
|| e.keyCode == SWT.ARROW_RIGHT) {
try (Finally bulkChange = model.beginBulkChange()) {
Orientation o = orientationForKeyCode(e.keyCode);
int gridSpacing = GridUtils.getGridSpacing(world);
int distance = gridSpacing == 0 ? 5 : gridSpacing;
boolean nudged = false;
Runnable undoRunnable = BNAOperations.takeSnapshotOfLocations(model, BNAUtils.getSelectedThings(model));
for (IThing t : BNAUtils.getSelectedThings(model)) {
if (t instanceof IHasReferencePoint) {
nudged = true;
nudge(o, distance, (IHasReferencePoint) t);
}
}
if (nudged) {
Runnable redoRunnable =
BNAOperations.takeSnapshotOfLocations(model, BNAUtils.getSelectedThings(model));
BNAOperations.runnable("Nudge", undoRunnable, redoRunnable, false);
}
}
}
}
@Override
public void keyReleased(IBNAView view, KeyType type, KeyEvent e) {
}
private Orientation orientationForKeyCode(int keyCode) {
switch (keyCode) {
case SWT.ARROW_LEFT:
return Orientation.WEST;
case SWT.ARROW_UP:
return Orientation.NORTH;
case SWT.ARROW_RIGHT:
return Orientation.EAST;
case SWT.ARROW_DOWN:
return Orientation.SOUTH;
default:
throw new IllegalArgumentException("Invalid key code");
}
}
private Point nudge(Orientation o, int distance, Point p) {
Point p2 = new Point(p.x, p.y);
switch (o) {
case NORTH:
p2.y -= distance;
break;
case EAST:
p2.x += distance;
break;
case SOUTH:
p2.y += distance;
break;
case WEST:
p2.x -= distance;
break;
default:
throw new IllegalArgumentException();
}
return p2;
}
protected void nudge(Orientation o, int distance, IHasReferencePoint t) {
if (UserEditableUtils.isEditableForAllQualities(t, IHasMutableReferencePoint.USER_MAY_MOVE)) {
t.setReferencePoint(nudge(o, distance, t.getReferencePoint()));
}
}
}