Commit 5a556945 authored by Nico Mack's avatar Nico Mack

Cleanup of code. Implemented cloning of widgets, required by feature

allowing mutliple widgets with identical IDs.
parent 5e2bc616
...@@ -171,6 +171,7 @@ STYLESHEET_NODE=styleSheet ...@@ -171,6 +171,7 @@ STYLESHEET_NODE=styleSheet
STYLERULE_NODE=rule STYLERULE_NODE=rule
PATH_NODE=path PATH_NODE=path
PAGE_NODE=page
MEDIA_NODE=media MEDIA_NODE=media
LOCATION_NODE=location LOCATION_NODE=location
......
/**
* Copyright Luxembourg Institute of Science and Technology, 2016.
*
* This file is part of TULIP.
*
* TULIP is licensed under a dual-licensing scheme. For non-commercial purposes, the LGPL version 3,
* as stated below, is applicable. For all commercial purposes TULIP is licensed under a LIST
* proprietary license. Please contact LIST at tto@list.lu to obtain a commercial license.
*
* For all non-commercial purposes, TULIP is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, version 3 of the License.
*
* TULIP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with TULIP. If
* not, see <http://www.gnu.org/licenses/lgpl-3.0.html>.
*/
package lu.list.itis.dkd.tui.content;
import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
import lu.list.itis.dkd.dbc.annotation.Nullable;
import lu.list.itis.dkd.tui.utility.Point;
import lu.list.itis.dkd.tui.widget.ZoomWidget;
/**
* Interface imposing functionality in order to be used with the {@link ZoomWidget}.
*
* @author Eric Tobias [eric.tobias@list.lu]
* @since 1.0
* @version 2.3.0
*/
@NonNullByDefault
public interface Zoomable {
/**
* Method used to specify the initial position of the zoom.
*
* @param 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
* the parameter is positive or negative.
*
* @param position
* Zoom factor contained in a {@link Point}.
*/
public void zoom(@Nullable Point position);
/**
* Method called by the manager handling the {@link Zoomable} instance when the state changed to
* where it is no longer considered zooming. This method provides the opportunity to run code
* only executable when the zooming stopped.
*/
public void stoppedZooming();
/**
* Method called by the manager handling the {@link Zoomable} instance when the state changed to
* where it is no longer considered moving. This method provides the opportunity to run code
* only executable when the moving stopped.
*/
public void stoppedMoving();
}
\ No newline at end of file
...@@ -215,6 +215,7 @@ public class Externalization extends NLS { ...@@ -215,6 +215,7 @@ public class Externalization extends NLS {
public static String POINTING_OFFSET_NODE; public static String POINTING_OFFSET_NODE;
public static String PATH_NODE; public static String PATH_NODE;
public static String PAGE_NODE;
public static String MEDIA_NODE; public static String MEDIA_NODE;
public static String LOCATION_NODE; public static String LOCATION_NODE;
......
...@@ -441,22 +441,6 @@ public class Point extends Float implements KdComparator<Point> { ...@@ -441,22 +441,6 @@ public class Point extends Float implements KdComparator<Point> {
return clone(); return clone();
} }
// switch (state.getClass().getSimpleName()) {
// case "TableCoordinates": //$NON-NLS-1$
// point.toTableCoordinates();
// break;
// case "ScreenCoordinates": //$NON-NLS-1$
// point.toScreenCoordinates();
// break;
// case "CameraCoordinates": //$NON-NLS-1$
// point.toCameraCoordinates();
// break;
// default:
// logger.error("This should never happen! State: {}!", state.toString()); //$NON-NLS-1$
// break;
// }
point.getState().toCoordinates(point, this.state.getClass()); point.getState().toCoordinates(point, this.state.getClass());
Point clone = clone(); Point clone = clone();
......
...@@ -36,36 +36,53 @@ import java.util.ArrayList; ...@@ -36,36 +36,53 @@ import java.util.ArrayList;
* @since 1.0 * @since 1.0
* @version 2.3.0 * @version 2.3.0
*/ */
// ***************************************************************************
// * Class Definition and Members *
// ***************************************************************************
@NonNullByDefault @NonNullByDefault
public class ContentWidget extends BaseWidget { public class ContentWidget extends BaseWidget {
/** List of {@link ContentEventListener} instances listening to updates to content. */ /** List of {@link ContentEventListener} instances listening to updates to content. */
protected ArrayList<ContentEventListener> listeners = new ArrayList<>(); protected ArrayList<ContentEventListener> listeners = new ArrayList<>();
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Constructor(s)
// ***************************************************************************
// ---------------------------------------------------------------------------
/** /**
* Constructor making use of the super constructor to initialise all fields. * Constructor making use of the super constructor to initialise all fields.
* *
* @param builder * @param builder
* The builder instance defining all parameters. * The builder instance defining all parameters.
*/ */
// ---------------------------------------------------------------------------
public ContentWidget(BaseContentBuilder<?> builder) { public ContentWidget(BaseContentBuilder<?> builder) {
super(builder); super(builder);
listeners = builder.listeners; listeners = builder.listeners;
} }
// ---------------------------------------------------------------------------
/** /**
* Method invoked when the tangible is detected on the table surface for the first time. The * Copy constructor to clone widget.
* {@link BaseWidget} instance is set to be active.
* *
* @param tangibleObject * @param original
* The {@link TangibleObject} that triggered the drop action. * specifies the original widget to create an exact copy from.
*/ */
@Override // ---------------------------------------------------------------------------
public void actionDrop(TangibleObject tangibleObject) {
super.actionDrop(tangibleObject);
notify(this, tangibleObject.getObjectId(), ContentEventType.DROP);
}
public ContentWidget(ContentWidget original) {
super(original);
listeners = new ArrayList<>(original.listeners);
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Primitive(s)
// ***************************************************************************
// ---------------------------------------------------------------------------
/** /**
* Method used to notify all listeners to a specific event. * Method used to notify all listeners to a specific event.
* *
...@@ -76,26 +93,35 @@ public class ContentWidget extends BaseWidget { ...@@ -76,26 +93,35 @@ public class ContentWidget extends BaseWidget {
* @param type * @param type
* The type of the triggered event. * The type of the triggered event.
*/ */
// ---------------------------------------------------------------------------
private void notify(ContentWidget widget, int handleID, ContentEventType type) { private void notify(ContentWidget widget, int handleID, ContentEventType type) {
for (ContentEventListener listener : listeners) { for (ContentEventListener listener : listeners) {
listener.contentUpdated(new ContentEvent(widget, handleID, type)); listener.contentUpdated(new ContentEvent(widget, handleID, type));
} }
} }
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Class Body
// ***************************************************************************
// ---------------------------------------------------------------------------
/** /**
* Method invoked when the tangible is removed from the table surface. The {@link BaseWidget} * Method invoked when the tangible is detected on the table surface for the first time. The
* instance will be set to no longer be active. * {@link BaseWidget} instance is set to be active.
* *
* @param tangibleObject * @param tangibleObject
* The {@link TangibleObject} that was triggering the lift action. * The {@link TangibleObject} that triggered the drop action.
*/ */
// ---------------------------------------------------------------------------
@Override @Override
public void actionLift(TangibleObject tangibleObject) { public void actionDrop(TangibleObject tangibleObject) {
super.actionLift(tangibleObject); super.actionDrop(tangibleObject);
notify(this, tangibleObject.getObjectId(), ContentEventType.LIFT); notify(this, tangibleObject.getObjectId(), ContentEventType.DROP);
} }
// ---------------------------------------------------------------------------
/** /**
* Method invoked when a handle associated with the widget was moved. This default * Method invoked when a handle associated with the widget was moved. This default
* implementation will set the base and angle fields to the corresponding values and update the * implementation will set the base and angle fields to the corresponding values and update the
...@@ -104,13 +130,31 @@ public class ContentWidget extends BaseWidget { ...@@ -104,13 +130,31 @@ public class ContentWidget extends BaseWidget {
* @param tangibleObject * @param tangibleObject
* The {@link TangibleObject} that was triggering the move. * The {@link TangibleObject} that was triggering the move.
*/ */
// ---------------------------------------------------------------------------
@Override @Override
public void actionMove(TangibleObject tangibleObject) { public void actionMove(TangibleObject tangibleObject) {
super.actionMove(tangibleObject); super.actionMove(tangibleObject);
notify(this, tangibleObject.getObjectId(), ContentEventType.MANIPULATION); notify(this, tangibleObject.getObjectId(), ContentEventType.MANIPULATION);
} }
// ---------------------------------------------------------------------------
/**
* Method invoked when the tangible is removed from the table surface. The {@link BaseWidget}
* instance will be set to no longer be active.
*
* @param tangibleObject
* The {@link TangibleObject} that was triggering the lift action.
*/
// ---------------------------------------------------------------------------
@Override
public void actionLift(TangibleObject tangibleObject) {
super.actionLift(tangibleObject);
notify(this, tangibleObject.getObjectId(), ContentEventType.LIFT);
}
// ---------------------------------------------------------------------------
/** /**
* Method used to determine which segment the rotation of a handle is in given the number of * Method used to determine which segment the rotation of a handle is in given the number of
* segments to cover by one rotation. * segments to cover by one rotation.
...@@ -120,13 +164,25 @@ public class ContentWidget extends BaseWidget { ...@@ -120,13 +164,25 @@ public class ContentWidget extends BaseWidget {
* @param handleID * @param handleID
* The ID of the handle to check the rotation for. * The ID of the handle to check the rotation for.
* @return The segment the rotation is currently in given:<br> * @return The segment the rotation is currently in given:<br>
* <code>rotation / (PI / totalSegments)</code>. * <code>rotation / (2*PI / totalSegments)</code>.
*/ */
public int getSegment(int totalSegments, int handleID) { // ---------------------------------------------------------------------------
// float rotation = Math.abs(positions.get(handleID).getAngle());
float rotation = Math.abs(getPosition(handleID).getAngle()); // public int getSegment(int totalSegments, int handleID) {
float segmentSize = (float) (2 * Math.PI / totalSegments); // Preconditions.checkArgument(totalSegments > 0, "Number of segments MUST be greater than 0!");
// //$NON-NLS-1$
//
// double rotation = Math.abs(getPosition(handleID).getAngle() % TWO_PI);
// double segmentSize = (float) (TWO_PI / totalSegments);
//
// return (int) Math.floor(rotation / segmentSize);
// }
// ---------------------------------------------------------------------------
return (int) Math.floor(rotation / segmentSize); @Override
public ContentWidget clone() {
return new ContentWidget(this);
} }
} }
\ No newline at end of file
...@@ -35,27 +35,60 @@ import org.slf4j.LoggerFactory; ...@@ -35,27 +35,60 @@ import org.slf4j.LoggerFactory;
/** /**
* Widget used to display information in a box next to the summit of a, usually, triangular shape. * Widget used to display information in a box next to the summit of a, usually, triangular shape.
* *
* @author Nico Mack [nico.mack@list.lu]
* @author Eric Tobias [eric.tobias@list.lu] * @author Eric Tobias [eric.tobias@list.lu]
* @since 1.0 * @since 1.0
* @version 2.3.0 * @version 2.5.0
*/ */
// ***************************************************************************
// * Class Definition and Members *
// ***************************************************************************
@NonNullByDefault @NonNullByDefault
public class InfoWidget extends TetherableWidget implements TetherListener { public class InfoWidget extends TetherableWidget implements TetherListener {
private static Logger LOGGER = LoggerFactory.getLogger(InfoWidget.class.getSimpleName()); private static final Logger LOGGER = LoggerFactory.getLogger(InfoWidget.class.getSimpleName());
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Constructor(s)
// ***************************************************************************
// ---------------------------------------------------------------------------
/** /**
* Constructor setting all fields by calling the super constructor. * Constructor setting all fields by calling the super constructor.
* *
* @param builder * @param builder
* The builder instance defining all parameters. * The builder instance defining all parameters.
*/ */
// ---------------------------------------------------------------------------
public InfoWidget(BaseInfoBuilder<InfoWidgetBuilder> builder) { public InfoWidget(BaseInfoBuilder<InfoWidgetBuilder> builder) {
super(builder); super(builder);
this.addTetherListener(this); this.addTetherListener(this);
} }
// ---------------------------------------------------------------------------
/**
* Copy constructor to clone widget.
*
* @param original
* specifies the original widget to create an exact copy from.
*/
// ---------------------------------------------------------------------------
public InfoWidget(InfoWidget original) {
super(original);
this.addTetherListener(this);
}
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Class Body
// ***************************************************************************
// ---------------------------------------------------------------------------
/** {@inheritDoc} */ /** {@inheritDoc} */
// ---------------------------------------------------------------------------
@Override @Override
public void tetherChanged(TetherEvent event) { public void tetherChanged(TetherEvent event) {
switch (event.getState()) { switch (event.getState()) {
...@@ -90,6 +123,12 @@ public class InfoWidget extends TetherableWidget implements TetherListener { ...@@ -90,6 +123,12 @@ public class InfoWidget extends TetherableWidget implements TetherListener {
break; break;
} }
}// TODO Auto-generated method stub }
// ---------------------------------------------------------------------------
// ***************************************************************************
// * End of Class
// ***************************************************************************
// ---------------------------------------------------------------------------
} }
\ No newline at end of file
...@@ -6,6 +6,10 @@ import lu.list.itis.dkd.tui.utility.PolarCoordinateHelper; ...@@ -6,6 +6,10 @@ import lu.list.itis.dkd.tui.utility.PolarCoordinateHelper;
import lu.list.itis.dkd.tui.widget.builder.BasePointingWidgetBuilder; import lu.list.itis.dkd.tui.widget.builder.BasePointingWidgetBuilder;
/** /**
* Widget used to point at something on the table. Pointing implies that one particular point of the
* widgets' shape is considered as a pointer. The PointingWidget class implements functionality to
* find the position of this pointing location.
*
* @author nmack * @author nmack
* @date 14 Jul 2017 * @date 14 Jul 2017
* *
...@@ -35,12 +39,29 @@ public abstract class PointingWidget extends StatefulWidget { ...@@ -35,12 +39,29 @@ public abstract class PointingWidget extends StatefulWidget {
* *
* @param builder * @param builder
*/ */
// ---------------------------------------------------------------------------
public PointingWidget(BasePointingWidgetBuilder<?> builder) { public PointingWidget(BasePointingWidgetBuilder<?> builder) {
super(builder); super(builder);
pointingOffset = builder.pointingOffset; pointingOffset = builder.pointingOffset;
} }
// ---------------------------------------------------------------------------
/**
* Copy constructor to clone widget.
*
* @param original
* specifies the original widget to create an exact copy from.
*/
// ---------------------------------------------------------------------------
public PointingWidget(PointingWidget original) {
super(original);
pointingOffset = original.pointingOffset;
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// *************************************************************************** // ***************************************************************************
// * Primitives * // * Primitives *
...@@ -76,8 +97,6 @@ public abstract class PointingWidget extends StatefulWidget { ...@@ -76,8 +97,6 @@ public abstract class PointingWidget extends StatefulWidget {
// *************************************************************************** // ***************************************************************************
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// *************************************************************************** // ***************************************************************************
// * End of Class * // * End of Class *
......
...@@ -30,23 +30,34 @@ import lu.list.itis.dkd.tui.widget.state.StateManager; ...@@ -30,23 +30,34 @@ import lu.list.itis.dkd.tui.widget.state.StateManager;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import java.util.Collection; import java.util.Collection;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
/** /**
* A widget implementation which adds a {@link NuiState} to the widget keeping track of state * A widget implementation which adds a {@link NuiState} to the widget keeping track of state
* transitions and the actual state. * transitions and the actual state.
* *
* @author Nico Mack [nico.mack@list.lu]
* @author Eric Tobias [eric.tobias@list.lu] * @author Eric Tobias [eric.tobias@list.lu]
* @since 1.0 * @since 1.0
* @version 2.3.0 * @version 2.5.0
*/ */
// ***************************************************************************
// * Class Definition and Members *
// ***************************************************************************
@NonNullByDefault @NonNullByDefault
public class StatefulWidget extends BaseWidget { public class StatefulWidget extends BaseWidget {
/** The coalesced NuiState instances per handle. */ /** The coalesced NuiState instances per handle. */
protected ConcurrentHashMap<Integer, StateManager> states; protected ConcurrentHashMap<Integer, StateManager> states;
/** Fields to track changes in position and rotation. */ /** Fields to track changes in position and rotation. */
protected Point rotationDelta, movementDelta; // protected Point rotationDelta, movementDelta;
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Constructor(s)
// ***************************************************************************
// ---------------------------------------------------------------------------
/** /**
* Constructor setting all fields as by the values specified by the builder. * Constructor setting all fields as by the values specified by the builder.
* *
...@@ -57,10 +68,36 @@ public class StatefulWidget extends BaseWidget { ...@@ -57,10 +68,36 @@ public class StatefulWidget extends BaseWidget {
super(builder); super(builder);
Preconditions.checkState(builder.states != null); Preconditions.checkState(builder.states != null);
states = builder.states; states = builder.states;
rotationDelta = new Point(0, 0, 0); // rotationDelta = new Point(0, 0, 0);
movementDelta = new Point(0, 0, 0); // movementDelta = new Point(0, 0, 0);
}
// ---------------------------------------------------------------------------
/**
* Copy constructor to clone widget.
*
* @param original
* specifies the original widget to create an exact copy from.
*/
// ---------------------------------------------------------------------------
public StatefulWidget(StatefulWidget original) {
super(original);
states = new ConcurrentHashMap<>();
for (Entry<Integer, StateManager> entry : original.states.entrySet()) {
boolean isPersistent = entry.getValue().isPersistent();
states.putIfAbsent(entry.getKey(), new StateManager(isPersistent));
}
// rotationDelta = new Point(0, 0, 0);
// movementDelta = new Point(0, 0, 0);
} }
// ---------------------------------------------------------------------------
// ***************************************************************************
// * Class Body
// ***************************************************************************
// ---------------------------------------------------------------------------
/** /**
* Allows checking wether this stateful widget is persistent or not. Persistent widgets remain * Allows checking wether this stateful widget is persistent or not. Persistent widgets remain
* logically active even though they are physically removed (lifted) from the table * logically active even though they are physically removed (lifted) from the table
...@@ -69,12 +106,14 @@ public class StatefulWidget extends BaseWidget { ...@@ -69,12 +106,14 @@ public class StatefulWidget extends BaseWidget {
* specifies the object to check the persistence state of * specifies the object to check the persistence state of
* @return <code>true</code> if specified object is persistent, <code>false</code> if not. * @return <code>true</code> if specified object is persistent, <code>false</code> if not.