Commit b98c940b authored by Eric Tobias's avatar Eric Tobias

Added FunctionWidget and related builders, some bugfixes and additional getters for core classes

+ Added FunctionWidget
+ Added FunctionWidgetBuilder
+ Added BaseFunctionWidgetBuilder
+ Added getter for the Shape held by a Corona
+ Added method to retrieve a shape relative to the current position of the centre of the Corona

~ A few bugfixes all around.
parent 033168d7
......@@ -181,14 +181,7 @@ public abstract class TangibleObjectManager {
* The widget for which to retrieve all mapped handle IDs.
* @return An {@link ArrayList} containing all associated handle IDs.
*/
public static synchronized ArrayList<Integer> getIdentifier(BaseWidget widget) {
// ArrayList<Integer> identifiers = new ArrayList<>();
//
// identifiers.addAll(objectList.keySet());
// identifiers.addAll(cursorList.keySet());
// identifiers.addAll(blobList.keySet());
//
// return identifiers;
public static synchronized ArrayList<Integer> getIdentifiers(BaseWidget widget) {
return new ArrayList<>(widget.getPositions().keySet());
}
......
......@@ -26,13 +26,13 @@ import lu.list.itis.dkd.tui.event.SpatialEventListener;
import lu.list.itis.dkd.tui.utility.Point;
import lu.list.itis.dkd.tui.utility.PropertiesFetcher;
import lu.list.itis.dkd.tui.widget.BaseWidget;
import lu.list.itis.dkd.tui.widget.corona.Corona;
import com.google.common.base.Preconditions;
import java.awt.Rectangle;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
......@@ -396,7 +396,7 @@ public class SpatialPositioningManager implements SpatialEventListener {
* @return A list of widgets that are to the left, either all or only those that are aligned.
*/
public ArrayList<BaseWidget> getWidgetsToLeftOf(BaseWidget widget, boolean aligned) {
ArrayList<BaseWidget> widgets = objectsToWidgets(spatialMatrix.leftOf(TangibleObjectManager.getIdentifier(widget)));
ArrayList<BaseWidget> widgets = objectsToWidgets(spatialMatrix.leftOf(TangibleObjectManager.getIdentifiers(widget)));
if (aligned) {
widgets.retainAll(getAlignedWidgets(widgets, widget, SpatialAlignment.HORIZONTAL));
}
......@@ -404,7 +404,7 @@ public class SpatialPositioningManager implements SpatialEventListener {
}
public List<TangibleObject> getObjectToLeftOf(BaseWidget widget) {
return spatialMatrix.leftOf(TangibleObjectManager.getIdentifier(widget));
return spatialMatrix.leftOf(TangibleObjectManager.getIdentifiers(widget));
}
/**
......@@ -421,7 +421,7 @@ public class SpatialPositioningManager implements SpatialEventListener {
* @return A list of widgets that are to the left, either all or only those that are aligned.
*/
public ArrayList<BaseWidget> getWidgetsToRightOf(BaseWidget widget, boolean aligned) {
ArrayList<BaseWidget> widgets = objectsToWidgets(spatialMatrix.rightOf(TangibleObjectManager.getIdentifier(widget)));
ArrayList<BaseWidget> widgets = objectsToWidgets(spatialMatrix.rightOf(TangibleObjectManager.getIdentifiers(widget)));
if (aligned) {
widgets.retainAll(getAlignedWidgets(widgets, widget, SpatialAlignment.HORIZONTAL));
}
......@@ -444,7 +444,7 @@ public class SpatialPositioningManager implements SpatialEventListener {
*/
@SuppressWarnings("unchecked")
public <T extends BaseWidget> List<T> getWidgetsToRightOf(BaseWidget widget, boolean aligned, Class<T> _class) {
List<BaseWidget> widgets = objectsToWidgets(spatialMatrix.rightOf(TangibleObjectManager.getIdentifier(widget)));
List<BaseWidget> widgets = objectsToWidgets(spatialMatrix.rightOf(TangibleObjectManager.getIdentifiers(widget)));
widgets = widgets.stream().filter(_widget -> _widget.getClass().equals(_class)).collect(Collectors.toList());
if (aligned) {
......@@ -466,7 +466,7 @@ public class SpatialPositioningManager implements SpatialEventListener {
* @return A list of widgets that are above, either all or only those that are aligned.
*/
public ArrayList<BaseWidget> getWidgetsAboveOf(BaseWidget widget, boolean aligned) {
ArrayList<BaseWidget> widgets = objectsToWidgets(spatialMatrix.above(TangibleObjectManager.getIdentifier(widget)));
ArrayList<BaseWidget> widgets = objectsToWidgets(spatialMatrix.above(TangibleObjectManager.getIdentifiers(widget)));
if (aligned) {
widgets.retainAll(getAlignedWidgets(widgets, widget, SpatialAlignment.VERTICAL));
}
......@@ -482,11 +482,11 @@ public class SpatialPositioningManager implements SpatialEventListener {
* @param widget
* The widget to retrieve all other aligned or non-aligned widgets below.
* @param aligned
* Whether all widgets (above) are retrieved or only those that are vertically aligned.
* Whether all widgets (below) are retrieved or only those that are vertically aligned.
* @return A list of widgets that are below, either all or only those that are aligned.
*/
public ArrayList<BaseWidget> getWidgetsBelowOf(BaseWidget widget, boolean aligned) {
ArrayList<BaseWidget> widgets = objectsToWidgets(spatialMatrix.below(TangibleObjectManager.getIdentifier(widget)));
ArrayList<BaseWidget> widgets = objectsToWidgets(spatialMatrix.below(TangibleObjectManager.getIdentifiers(widget)));
if (aligned) {
widgets.retainAll(getAlignedWidgets(widgets, widget, SpatialAlignment.VERTICAL));
}
......@@ -509,28 +509,82 @@ public class SpatialPositioningManager implements SpatialEventListener {
* returned widgets defining shape's max and minimum y-axis coordinates.
*/
private Set<BaseWidget> getAlignedWidgets(List<BaseWidget> widgets, BaseWidget widget, SpatialAlignment alignment) {
Collection<Point> centres = widget.getPositions().values();
Set<BaseWidget> alignedWidgets = new HashSet<>();
for (BaseWidget _widget : widgets) {
if (null == _widget.getDefiningShape()) {
continue;
}
for (Point centre : centres) {
if (areAligned(_widget.getDefiningShape().getBounds(), centre, alignment)) {
alignedWidgets.add(_widget);
for (Corona corona : widget.getCoronas()) {
for (BaseWidget potentiallyAlignedWidget : widgets) {
if (areAligned(corona, potentiallyAlignedWidget.getCoronas(), alignment)) {
alignedWidgets.add(potentiallyAlignedWidget);
}
}
}
return alignedWidgets;
// Collection<Point> centres = widget.getPositions().values();
// Set<BaseWidget> alignedWidgets = new HashSet<>();
// for (BaseWidget _widget : widgets) {
// if (null == _widget.getDefiningShape()) {
// continue;
// }
//
// for (Point centre : centres) {
// if (areAligned(_widget.getDefiningShape().getBounds(), centre, alignment)) {
// alignedWidgets.add(_widget);
// }
// }
// }
// return alignedWidgets;
}
// private Collection<Corona> getCoronas(List<BaseWidget> widgets) {
// Set<Corona> coronas = new HashSet<>();
//
// widgets.forEach(widget -> coronas.addAll(widget.getCoronas()));
//
// return coronas;
// }
/**
* @param corona
* @param coronas
* @param alignment
* @return
*/
private boolean areAligned(Corona corona, List<Corona> coronas, SpatialAlignment alignment) {
if (null == corona.getShape()) {
return false;
}
Rectangle bounds = corona.getShapeRelativeToCentre().getBounds();
for (Corona potentiallyAlignedCorona : coronas) {
Point point = potentiallyAlignedCorona.getHandleCentre().toScreenCoordinates();
switch (alignment) {
case HORIZONTAL:
if (Double.compare(point.getY(), bounds.getMinY()) >= 0 && Double.compare(point.getY(), bounds.getMaxY()) <= 0) {
return true;
}
break;
case VERTICAL:
if (Double.compare(point.getX(), bounds.getMinX()) >= 0 && Double.compare(point.getX(), bounds.getMaxX()) <= 0) {
return true;
}
break;
default:
logger.log(Level.WARNING, "The spatial alignment constant " + alignment + " could not be recognized!"); //$NON-NLS-1$ //$NON-NLS-2$
return false;
}
}
return false;
}
private boolean areAligned(Rectangle bounds, Point point, SpatialAlignment alignment) {
switch (alignment) {
case HORIZONTAL:
return (Double.compare(point.getY(), bounds.getMinY()) >= 0 || Double.compare(point.getY(), bounds.getMaxY()) <= 0);
return (Double.compare(point.getY(), bounds.getMinY()) >= 0 && Double.compare(point.getY(), bounds.getMaxY()) <= 0);
case VERTICAL:
return (Double.compare(point.getX(), bounds.getMinX()) >= 0 || Double.compare(point.getX(), bounds.getMaxX()) <= 0);
return (Double.compare(point.getX(), bounds.getMinX()) >= 0 && Double.compare(point.getX(), bounds.getMaxX()) <= 0);
default:
logger.log(Level.WARNING, "The spatial alignment constant " + alignment + " could not be recognized!"); //$NON-NLS-1$ //$NON-NLS-2$
return false;
......
......@@ -188,6 +188,16 @@ public class BaseWidget {
return results;
}
/**
* Method for retrieving all coronas held by any of the handles associated to this widget.
*
* @return A {@link List} holding all coronas that are attached to any of the handles associated
* to this {@link BaseWidget}'s concrete instance.
*/
public List<Corona> getCoronas() {
return new ArrayList<>(coronas.values());
}
/**
* Method returning all {@link Corona} instances that are forming the visual background.
*
......
/**
* Copyright Luxembourg Institute of Science and Technology, 2015. All rights reserved.
*
* This file is part of TULIP.
*
* 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.widget;
import lu.list.itis.dkd.tui.adapter.TangibleObject;
import lu.list.itis.dkd.tui.widget.builder.BaseFunctionWidgetBuilder;
import java.util.Timer;
import java.util.TimerTask;
/**
* @author Eric Tobias [eric.tobias@list.lu]
* @since [major].[minor]
* @version [major].[minor].[micro]
*/
public class FunctionWidget extends BaseWidget {
private Runnable runnable;
private Timer cooldownTimer;
private boolean coolingDown = false;
/**
* @param builder
*/
public FunctionWidget(BaseFunctionWidgetBuilder<?> builder) {
super(builder);
this.runnable = builder.runnable;
cooldownTimer = new Timer();
}
@Override
public synchronized void actionDrop(TangibleObject tangibleObject) {
super.actionDrop(tangibleObject);
if (!coolingDown) {
runnable.run();
coolingDown = true;
cooldownTimer.schedule(new TimerTask() {
public void run() {
coolingDown = false;
}
}, 2000);
}
}
}
/**
* Copyright Luxembourg Institute of Science and Technology, 2015. All rights reserved.
*
* This file is part of TULIP.
*
* 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.widget.builder;
import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
import lu.list.itis.dkd.tui.widget.FunctionWidget;
/**
* Builder serving as abstract super class for all content builders.
*
* @author Eric TOBIAS [eric.tobias@list.lu]
* @since 2.1
* @version 2.1.4
* @param <B>
* The concrete builder.
*/
@NonNullByDefault
public abstract class BaseFunctionWidgetBuilder<B extends BaseFunctionWidgetBuilder<B>> extends BaseBuilder<B> {
public Runnable runnable;
@SuppressWarnings("unchecked")
public B withRunnable(Runnable runnable) {
this.runnable = runnable;
return (B) this;
}
/** {@inheritDoc} */
@Override
public abstract FunctionWidget build();
}
\ No newline at end of file
/**
* Copyright Luxembourg Institute of Science and Technology, 2015. All rights reserved.
*
* This file is part of TULIP.
*
* 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.widget.builder;
import lu.list.itis.dkd.tui.widget.FunctionWidget;
/**
* @author Eric Tobias [eric.tobias@list.lu]
* @since 2.1
* @version 2.1.4
*/
public class FunctionWidgetBuilder extends BaseFunctionWidgetBuilder<FunctionWidgetBuilder> {
/** {@inheritDoc} */
@Override
public FunctionWidget build() {
return new FunctionWidget(this);
}
}
\ No newline at end of file
......@@ -292,6 +292,33 @@ public abstract class Corona implements Comparable<Corona> {
return relativePoint;
}
public Shape getShapeRelativeToCentre() {
centre.toScreenCoordinates();
if (initialTranslation != null) {
initialTranslation.toScreenCoordinates();
}
Point drawAt = centre.add(initialTranslation);
AffineTransform transformation = new AffineTransform();
transformation.translate(drawAt.getX(), drawAt.getY());
if (rotateWithHandle) {
transformation.rotate(drawAt.getAngle());
}
return transformation.createTransformedShape(shape);
}
/**
* Simple getter method for shape.
*
* @return The value of shape.
*/
public Shape getShape() {
return shape;
}
/**
* Method used to define behaviour of the corona when it should visualise on the table. By
* default, the call to {@link #onTable()} will result in {@link Corona} activation.
......
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