Commit aa9451d4 authored by Nico Mack's avatar Nico Mack

Properly encapsulates widget positions. Changes to Zoomable interface in

order to fix zooming issue
parent 6aa4bfec
...@@ -230,7 +230,7 @@ public abstract class TangibleObjectManager { ...@@ -230,7 +230,7 @@ public abstract class TangibleObjectManager {
* @return An {@link ArrayList} containing all associated handle IDs. * @return An {@link ArrayList} containing all associated handle IDs.
*/ */
public static synchronized ArrayList<Integer> getIdentifiers(BaseWidget widget) { public static synchronized ArrayList<Integer> getIdentifiers(BaseWidget widget) {
return new ArrayList<>(widget.getPositions().keySet()); return new ArrayList<>(widget.getWidgetIds());
} }
/** /**
......
...@@ -184,7 +184,7 @@ public class TangibleObjectBootstrapper extends TangibleObjectManager { ...@@ -184,7 +184,7 @@ public class TangibleObjectBootstrapper extends TangibleObjectManager {
try { try {
for (Element objectNode : objectNodes) { for (Element objectNode : objectNodes) {
BaseWidget widget = buildObjectFromElement(objectNode, null, null); BaseWidget widget = buildObjectFromElement(objectNode, null, null);
widget.getPositions().keySet().forEach(handleId -> objectMap.put(handleId, widget)); widget.getWidgetIds().forEach(handleId -> objectMap.put(handleId, widget));
} }
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException e) { } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchMethodException | SecurityException | IllegalArgumentException | InvocationTargetException e) {
......
...@@ -34,14 +34,23 @@ import lu.list.itis.dkd.tui.widget.ZoomWidget; ...@@ -34,14 +34,23 @@ import lu.list.itis.dkd.tui.widget.ZoomWidget;
*/ */
@NonNullByDefault @NonNullByDefault
public interface Zoomable { public interface Zoomable {
/** /**
* Method used to request all zooms be centred on the parameterised position. * Method used to specify the initial position of the zoom.
* *
* @param position * @param position
* The position to centre on.
*/ */
public void centre(Point position); public void centre(Point position);
/**
* Method used to request all zooms be translate to the specified position.
*
* @param position
* The position to centre on.
*/
public void translate(Point position);
/** /**
* Method used to zoom by a factor given as parameter The direction of the zoom depends whether * Method used to zoom by a factor given as parameter The direction of the zoom depends whether
* the parameter is positive or negative. * the parameter is positive or negative.
......
...@@ -38,6 +38,7 @@ import java.util.ArrayList; ...@@ -38,6 +38,7 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Set;
/** /**
* A simple widget implementation which sets some default behaviour for common methods. It also * A simple widget implementation which sets some default behaviour for common methods. It also
...@@ -54,7 +55,7 @@ public class BaseWidget { ...@@ -54,7 +55,7 @@ public class BaseWidget {
/** The visual components to display as part of the widget. It's background. */ /** The visual components to display as part of the widget. It's background. */
protected Multimap<Integer, Corona> coronas; protected Multimap<Integer, Corona> coronas;
/** The positions where the widget's handles are at. */ /** The positions where the widget's handles are at. */
protected HashMap<Integer, Point> positions; private HashMap<Integer, Point> positions;
/** The name given to this widget. */ /** The name given to this widget. */
protected String name; protected String name;
@Nullable @Nullable
...@@ -93,9 +94,6 @@ public class BaseWidget { ...@@ -93,9 +94,6 @@ public class BaseWidget {
* The {@link TangibleObject} that was triggering the move. * The {@link TangibleObject} that was triggering the move.
*/ */
public void actionMove(TangibleObject tangibleObject) { public void actionMove(TangibleObject tangibleObject) {
// EventLogger.getInstance().addObjInfo(tangibleObject.getObjectId(), tangibleObject.getX(),
// tangibleObject.getY(), tangibleObject.getAngle(), "move",
// tangibleObject.getTotalMilliseconds()); //$NON-NLS-1$
positions.put(tangibleObject.getObjectId(), new Point(tangibleObject.getX(), tangibleObject.getY(), tangibleObject.getAngle(), Math.signum(tangibleObject.getRotationSpeed()))); positions.put(tangibleObject.getObjectId(), new Point(tangibleObject.getX(), tangibleObject.getY(), tangibleObject.getAngle(), Math.signum(tangibleObject.getRotationSpeed())));
updateCoronas(tangibleObject.getObjectId()); updateCoronas(tangibleObject.getObjectId());
} }
...@@ -108,8 +106,9 @@ public class BaseWidget { ...@@ -108,8 +106,9 @@ public class BaseWidget {
*/ */
private void updateCoronas(int handleID) { private void updateCoronas(int handleID) {
assert positions.get(handleID) != null; assert positions.get(handleID) != null;
Point centre = getPosition(handleID);
for (Corona corona : coronas.get(handleID)) { for (Corona corona : coronas.get(handleID)) {
corona.setHandleCentre(positions.get(handleID)); corona.setHandleCentre(centre);
corona.invalidate(); corona.invalidate();
} }
} }
...@@ -122,9 +121,6 @@ public class BaseWidget { ...@@ -122,9 +121,6 @@ public class BaseWidget {
* The {@link TangibleObject} that was triggering the drop action. * The {@link TangibleObject} that was triggering the drop action.
*/ */
public void actionDrop(TangibleObject tangibleObject) { public void actionDrop(TangibleObject tangibleObject) {
// EventLogger.getInstance().addObjInfo(tangibleObject.getObjectId(), tangibleObject.getX(),
// tangibleObject.getY(), tangibleObject.getAngle(), "down",
// tangibleObject.getTotalMilliseconds()); //$NON-NLS-1$
actionMove(tangibleObject); actionMove(tangibleObject);
startDrawingIfAppropriate(tangibleObject.getObjectId()); startDrawingIfAppropriate(tangibleObject.getObjectId());
} }
...@@ -231,7 +227,13 @@ public class BaseWidget { ...@@ -231,7 +227,13 @@ public class BaseWidget {
* <code>null</code> if no such handle is managed. * <code>null</code> if no such handle is managed.
*/ */
public Point getPosition(int handleId) { public Point getPosition(int handleId) {
return positions.get(handleId); Point position = null;
if (positions.containsKey(handleId)) {
position = positions.get(handleId);
position = (position != null) ? position.clone() : null;
}
return position;
} }
/** /**
...@@ -245,7 +247,14 @@ public class BaseWidget { ...@@ -245,7 +247,14 @@ public class BaseWidget {
List<Integer> keys = new ArrayList<>(positions.keySet()); List<Integer> keys = new ArrayList<>(positions.keySet());
Collections.sort(keys, Ordering.natural()); Collections.sort(keys, Ordering.natural());
return positions.get(keys.get(0)); return this.getPosition(keys.get(0));
}
/**
* @return
*/
public Set<Integer> getWidgetIds() {
return positions.keySet();
} }
/** /**
...@@ -253,9 +262,9 @@ public class BaseWidget { ...@@ -253,9 +262,9 @@ public class BaseWidget {
* *
* @return The value of positions. * @return The value of positions.
*/ */
public HashMap<Integer, Point> getPositions() { // public HashMap<Integer, Point> getPositions() {
return positions; // return positions;
} // }
/** /**
......
...@@ -123,7 +123,8 @@ public class ContentWidget extends BaseWidget { ...@@ -123,7 +123,8 @@ public class ContentWidget extends BaseWidget {
* <code>rotation / (PI / totalSegments)</code>. * <code>rotation / (PI / totalSegments)</code>.
*/ */
public int getSegment(int totalSegments, int handleID) { public int getSegment(int totalSegments, int handleID) {
float rotation = Math.abs(positions.get(handleID).getAngle()); // float rotation = Math.abs(positions.get(handleID).getAngle());
float rotation = Math.abs(getPosition(handleID).getAngle());
float segmentSize = (float) (2 * Math.PI / totalSegments); float segmentSize = (float) (2 * Math.PI / totalSegments);
return (int) Math.floor(rotation / segmentSize); return (int) Math.floor(rotation / segmentSize);
......
...@@ -88,7 +88,7 @@ public class StatefulWidget extends BaseWidget { ...@@ -88,7 +88,7 @@ public class StatefulWidget extends BaseWidget {
StateManager manager = states.get(tangibleObject.getObjectId()); StateManager manager = states.get(tangibleObject.getObjectId());
super.actionMove(tangibleObject); super.actionMove(tangibleObject);
Point position = positions.get(tangibleObject.getObjectId()); Point position = getPosition(tangibleObject.getObjectId());
assert position != null; assert position != null;
manager.rotate(position).move(position); manager.rotate(position).move(position);
} }
...@@ -117,8 +117,8 @@ public class StatefulWidget extends BaseWidget { ...@@ -117,8 +117,8 @@ public class StatefulWidget extends BaseWidget {
*/ */
@Override @Override
public void actionLift(TangibleObject tangibleObject) { public void actionLift(TangibleObject tangibleObject) {
super.actionLift(tangibleObject);
states.get(tangibleObject.getObjectId()).lift(new Point(tangibleObject.getX(), tangibleObject.getY(), tangibleObject.getAngle())); states.get(tangibleObject.getObjectId()).lift(new Point(tangibleObject.getX(), tangibleObject.getY(), tangibleObject.getAngle()));
super.actionLift(tangibleObject);
} }
/** /**
......
...@@ -175,7 +175,7 @@ public abstract class TetherableWidget extends StatefulWidget implements Tethera ...@@ -175,7 +175,7 @@ public abstract class TetherableWidget extends StatefulWidget implements Tethera
public void actionMove(TangibleObject tangibleObject) { public void actionMove(TangibleObject tangibleObject) {
super.actionMove(tangibleObject); super.actionMove(tangibleObject);
Point position = positions.get(tangibleObject.getObjectId()); Point position = getPosition(tangibleObject.getObjectId());
this.tetherManager.move(position); this.tetherManager.move(position);
} }
......
...@@ -54,6 +54,9 @@ public class ZoomWidget extends StatefulWidget implements TimerEventListener { ...@@ -54,6 +54,9 @@ public class ZoomWidget extends StatefulWidget implements TimerEventListener {
private boolean synchronousZoom; private boolean synchronousZoom;
/** Field indicating whether the widget will recentre on zooming. */ /** Field indicating whether the widget will recentre on zooming. */
private boolean recentre; private boolean recentre;
private boolean onTable;
/** A {@link Logger} to log all messages during execution. */ /** A {@link Logger} to log all messages during execution. */
private static final Logger logger = LoggerFactory.getLogger(ZoomWidget.class.getSimpleName()); private static final Logger logger = LoggerFactory.getLogger(ZoomWidget.class.getSimpleName());
...@@ -73,6 +76,7 @@ public class ZoomWidget extends StatefulWidget implements TimerEventListener { ...@@ -73,6 +76,7 @@ public class ZoomWidget extends StatefulWidget implements TimerEventListener {
zoomLevel = builder.zoomLevel; zoomLevel = builder.zoomLevel;
synchronousZoom = builder.synchronousZoom; synchronousZoom = builder.synchronousZoom;
recentre = builder.centerOnZoom; recentre = builder.centerOnZoom;
onTable = false;
// TangibleApplication.configureLogger(logger); // TangibleApplication.configureLogger(logger);
} }
...@@ -108,22 +112,23 @@ public class ZoomWidget extends StatefulWidget implements TimerEventListener { ...@@ -108,22 +112,23 @@ public class ZoomWidget extends StatefulWidget implements TimerEventListener {
public void actionMove(TangibleObject tangibleObject) { public void actionMove(TangibleObject tangibleObject) {
StateManager manager = states.get(tangibleObject.getObjectId()); StateManager manager = states.get(tangibleObject.getObjectId());
Point position = positions.get(tangibleObject.getObjectId()); Point position = getPosition(tangibleObject.getObjectId());
double lastRotation;
double lastRotation = tangibleObject.getAngle();
if (position != null) { if (position != null) {
lastRotation = tangibleObject.getAngle() - position.getAngle(); lastRotation -= position.getAngle();
} else {
lastRotation = tangibleObject.getAngle();
} }
super.actionMove(tangibleObject); super.actionMove(tangibleObject);
if (position == null) { if (manager.isStill()) {
position = positions.get(tangibleObject.getObjectId()); for (Zoomable resource : resources.values()) {
resource.centre(position);
}
} }
if (synchronousZoom) { if (position != null && onTable && synchronousZoom) {
position.toCameraCoordinates(); position.toCameraCoordinates();
if (lastRotation > ONE_POINT_FIVE_PI) if (lastRotation > ONE_POINT_FIVE_PI)
lastRotation -= TWO_PI; lastRotation -= TWO_PI;
...@@ -135,13 +140,13 @@ public class ZoomWidget extends StatefulWidget implements TimerEventListener { ...@@ -135,13 +140,13 @@ public class ZoomWidget extends StatefulWidget implements TimerEventListener {
for (Zoomable resource : resources.values()) { for (Zoomable resource : resources.values()) {
resource.zoom(zoom); resource.zoom(zoom);
if (recentre) if (recentre)
resource.centre(position); resource.translate(zoom);
} }
} }
if (manager.isMoving()) { if (manager.isMoving()) {
for (Zoomable resource : resources.values()) { for (Zoomable resource : resources.values()) {
resource.centre(position); resource.translate(zoom);
} }
} }
} }
...@@ -153,6 +158,13 @@ public class ZoomWidget extends StatefulWidget implements TimerEventListener { ...@@ -153,6 +158,13 @@ public class ZoomWidget extends StatefulWidget implements TimerEventListener {
@Override @Override
public void actionDrop(TangibleObject tangibleObject) { public void actionDrop(TangibleObject tangibleObject) {
super.actionDrop(tangibleObject); super.actionDrop(tangibleObject);
onTable = true;
}
@Override
public void actionLift(TangibleObject tangibleObject) {
onTable = false;
super.actionLift(tangibleObject);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
......
...@@ -147,6 +147,7 @@ public abstract class Corona implements Comparable<Corona> { ...@@ -147,6 +147,7 @@ public abstract class Corona implements Comparable<Corona> {
drawingPoint = centre.add(initialTranslation); drawingPoint = centre.add(initialTranslation);
if (assetCentre != null) { if (assetCentre != null) {
drawingPoint.toCoordinates(ScreenCoordinates.class);
assetCentre.toCoordinates(ScreenCoordinates.class); assetCentre.toCoordinates(ScreenCoordinates.class);
drawingPoint = drawingPoint.subtract(assetCentre, false); drawingPoint = drawingPoint.subtract(assetCentre, false);
} }
......
...@@ -103,6 +103,8 @@ public class StateManager { ...@@ -103,6 +103,8 @@ public class StateManager {
private static final Logger logger = LoggerFactory.getLogger(StateManager.class.getSimpleName()); private static final Logger logger = LoggerFactory.getLogger(StateManager.class.getSimpleName());
public static final Point UNDEFINED = new Point(-10, -10, 0);
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// *************************************************************************** // ***************************************************************************
// * Constructor(s) // * Constructor(s)
...@@ -118,13 +120,13 @@ public class StateManager { ...@@ -118,13 +120,13 @@ public class StateManager {
public StateManager(boolean persistent) { public StateManager(boolean persistent) {
states = HashMultimap.create(); states = HashMultimap.create();
states.put(LimboState.class.getSimpleName(), new LimboState(new Point(-10, -10, 0))); states.put(LimboState.class.getSimpleName(), new LimboState(UNDEFINED));
rotationTimer.setRepeats(false); rotationTimer.setRepeats(false);
movementTimer.setRepeats(false); movementTimer.setRepeats(false);
listeners = new ArrayList<>(); listeners = new ArrayList<>();
lastPosition = new Point(-10, -10, 0); lastPosition = UNDEFINED;
this.isPersistent = persistent; this.isPersistent = persistent;
} }
...@@ -277,17 +279,13 @@ public class StateManager { ...@@ -277,17 +279,13 @@ public class StateManager {
@Override @Override
public void actionPerformed(@Nullable ActionEvent event) { public void actionPerformed(@Nullable ActionEvent event) {
rotationTimerExpired = true; rotationTimerExpired = true;
checkForConsistency(); // checkForConsistency();
wasRotating = true; wasRotating = true;
rotationTimer.stop(); rotationTimer.stop();
if (logger.isTraceEnabled()) { if (logger.isTraceEnabled()) {
logger.trace("Rotation stopped!"); //$NON-NLS-1$ logger.trace("Rotation stopped!"); //$NON-NLS-1$
} }
for (TimerEventListener listener : listeners) {
listener.stoppedRotating(new TimerEvent(StateManager.this));
}
} }
} }
...@@ -303,17 +301,13 @@ public class StateManager { ...@@ -303,17 +301,13 @@ public class StateManager {
@Override @Override
public void actionPerformed(@Nullable ActionEvent event) { public void actionPerformed(@Nullable ActionEvent event) {
movementTimerExpired = true; movementTimerExpired = true;
checkForConsistency(); // checkForConsistency();
wasMoving = true; wasMoving = true;
movementTimer.stop(); movementTimer.stop();
if (logger.isTraceEnabled()) { if (logger.isTraceEnabled()) {
logger.trace("Movement stopped!"); //$NON-NLS-1$ logger.trace("Movement stopped!"); //$NON-NLS-1$
} }
for (TimerEventListener listener : listeners) {
listener.stoppedMoving(new TimerEvent(StateManager.this));
}
} }
} }
...@@ -326,14 +320,25 @@ public class StateManager { ...@@ -326,14 +320,25 @@ public class StateManager {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
private synchronized void handleTimerExpiry() { private synchronized void handleTimerExpiry() {
if (movementTimerExpired) { if (movementTimerExpired) {
states.removeAll(MovementState.class.getSimpleName()); states.removeAll(MovementState.class.getSimpleName());
for (TimerEventListener listener : listeners) {
listener.stoppedMoving(new TimerEvent(StateManager.this));
}
movementTimerExpired = false; movementTimerExpired = false;
} }
if (rotationTimerExpired) { if (rotationTimerExpired) {
states.removeAll(RotationState.class.getSimpleName()); states.removeAll(RotationState.class.getSimpleName());
for (TimerEventListener listener : listeners) {
listener.stoppedRotating(new TimerEvent(StateManager.this));
}
rotationTimerExpired = false; rotationTimerExpired = false;
} }
if (movementTimerExpired || rotationTimerExpired) {
checkForConsistency();
}
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
......
...@@ -50,7 +50,7 @@ public class StatefulWidgetTest { ...@@ -50,7 +50,7 @@ public class StatefulWidgetTest {
assertNotNull(widget); assertNotNull(widget);
assertTrue(widget.coronas.containsKey(1)); assertTrue(widget.coronas.containsKey(1));
assertFalse(widget.coronas.containsKey(2)); assertFalse(widget.coronas.containsKey(2));
assertTrue(widget.positions.containsKey(1)); assertTrue(widget.getWidgetIds().contains(1));
assertTrue(widget.states.containsKey(1)); assertTrue(widget.states.containsKey(1));
assertNotNull(widget.states); assertNotNull(widget.states);
} }
......
...@@ -66,7 +66,7 @@ public class BaseBuilderBootstrappingTest { ...@@ -66,7 +66,7 @@ public class BaseBuilderBootstrappingTest {
BaseWidget widget = (BaseWidget) TangibleObjectManager.getWidgets().toArray()[0]; BaseWidget widget = (BaseWidget) TangibleObjectManager.getWidgets().toArray()[0];
assertEquals(4, widget.getPositions().size()); assertEquals(4, widget.getWidgetIds().size());
assertEquals(2, widget.getCoronas().size()); assertEquals(2, widget.getCoronas().size());
assertTrue(widget.getDefiningShape() instanceof Ellipse2D); assertTrue(widget.getDefiningShape() instanceof Ellipse2D);
assertTrue(widget.getNetworkAdapter() instanceof TcpServer); assertTrue(widget.getNetworkAdapter() instanceof TcpServer);
......
Markdown is supported
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