From b98c940b2a8cb172bbddfb6763780e9955989d96 Mon Sep 17 00:00:00 2001 From: Eric Tobias Date: Thu, 5 Nov 2015 17:06:18 +0100 Subject: [PATCH] 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. --- .../itis/dkd/tui/TangibleObjectManager.java | 9 +- .../tui/space/SpatialPositioningManager.java | 90 +++++++++++++++---- .../list/itis/dkd/tui/widget/BaseWidget.java | 10 +++ .../itis/dkd/tui/widget/FunctionWidget.java | 60 +++++++++++++ .../builder/BaseFunctionWidgetBuilder.java | 47 ++++++++++ .../widget/builder/FunctionWidgetBuilder.java | 33 +++++++ .../itis/dkd/tui/widget/corona/Corona.java | 27 ++++++ 7 files changed, 250 insertions(+), 26 deletions(-) create mode 100644 TULIP/src/lu/list/itis/dkd/tui/widget/FunctionWidget.java create mode 100644 TULIP/src/lu/list/itis/dkd/tui/widget/builder/BaseFunctionWidgetBuilder.java create mode 100644 TULIP/src/lu/list/itis/dkd/tui/widget/builder/FunctionWidgetBuilder.java diff --git a/TULIP/src/lu/list/itis/dkd/tui/TangibleObjectManager.java b/TULIP/src/lu/list/itis/dkd/tui/TangibleObjectManager.java index 1343b3a..782a822 100644 --- a/TULIP/src/lu/list/itis/dkd/tui/TangibleObjectManager.java +++ b/TULIP/src/lu/list/itis/dkd/tui/TangibleObjectManager.java @@ -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 getIdentifier(BaseWidget widget) { - // ArrayList identifiers = new ArrayList<>(); - // - // identifiers.addAll(objectList.keySet()); - // identifiers.addAll(cursorList.keySet()); - // identifiers.addAll(blobList.keySet()); - // - // return identifiers; + public static synchronized ArrayList getIdentifiers(BaseWidget widget) { return new ArrayList<>(widget.getPositions().keySet()); } diff --git a/TULIP/src/lu/list/itis/dkd/tui/space/SpatialPositioningManager.java b/TULIP/src/lu/list/itis/dkd/tui/space/SpatialPositioningManager.java index d8df817..bed2064 100644 --- a/TULIP/src/lu/list/itis/dkd/tui/space/SpatialPositioningManager.java +++ b/TULIP/src/lu/list/itis/dkd/tui/space/SpatialPositioningManager.java @@ -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 getWidgetsToLeftOf(BaseWidget widget, boolean aligned) { - ArrayList widgets = objectsToWidgets(spatialMatrix.leftOf(TangibleObjectManager.getIdentifier(widget))); + ArrayList 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 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 getWidgetsToRightOf(BaseWidget widget, boolean aligned) { - ArrayList widgets = objectsToWidgets(spatialMatrix.rightOf(TangibleObjectManager.getIdentifier(widget))); + ArrayList 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 List getWidgetsToRightOf(BaseWidget widget, boolean aligned, Class _class) { - List widgets = objectsToWidgets(spatialMatrix.rightOf(TangibleObjectManager.getIdentifier(widget))); + List 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 getWidgetsAboveOf(BaseWidget widget, boolean aligned) { - ArrayList widgets = objectsToWidgets(spatialMatrix.above(TangibleObjectManager.getIdentifier(widget))); + ArrayList 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 getWidgetsBelowOf(BaseWidget widget, boolean aligned) { - ArrayList widgets = objectsToWidgets(spatialMatrix.below(TangibleObjectManager.getIdentifier(widget))); + ArrayList 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 getAlignedWidgets(List widgets, BaseWidget widget, SpatialAlignment alignment) { - Collection centres = widget.getPositions().values(); Set 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 centres = widget.getPositions().values(); + // Set 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 getCoronas(List widgets) { + // Set 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 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; diff --git a/TULIP/src/lu/list/itis/dkd/tui/widget/BaseWidget.java b/TULIP/src/lu/list/itis/dkd/tui/widget/BaseWidget.java index 84ce68d..4c20f1a 100644 --- a/TULIP/src/lu/list/itis/dkd/tui/widget/BaseWidget.java +++ b/TULIP/src/lu/list/itis/dkd/tui/widget/BaseWidget.java @@ -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 getCoronas() { + return new ArrayList<>(coronas.values()); + } + /** * Method returning all {@link Corona} instances that are forming the visual background. * diff --git a/TULIP/src/lu/list/itis/dkd/tui/widget/FunctionWidget.java b/TULIP/src/lu/list/itis/dkd/tui/widget/FunctionWidget.java new file mode 100644 index 0000000..8d1e20a --- /dev/null +++ b/TULIP/src/lu/list/itis/dkd/tui/widget/FunctionWidget.java @@ -0,0 +1,60 @@ +/** + * 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 . + */ +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); + } + } +} diff --git a/TULIP/src/lu/list/itis/dkd/tui/widget/builder/BaseFunctionWidgetBuilder.java b/TULIP/src/lu/list/itis/dkd/tui/widget/builder/BaseFunctionWidgetBuilder.java new file mode 100644 index 0000000..bd3daed --- /dev/null +++ b/TULIP/src/lu/list/itis/dkd/tui/widget/builder/BaseFunctionWidgetBuilder.java @@ -0,0 +1,47 @@ +/** + * 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 . + */ +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 + * The concrete builder. + */ +@NonNullByDefault +public abstract class BaseFunctionWidgetBuilder> extends BaseBuilder { + + 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 diff --git a/TULIP/src/lu/list/itis/dkd/tui/widget/builder/FunctionWidgetBuilder.java b/TULIP/src/lu/list/itis/dkd/tui/widget/builder/FunctionWidgetBuilder.java new file mode 100644 index 0000000..7492461 --- /dev/null +++ b/TULIP/src/lu/list/itis/dkd/tui/widget/builder/FunctionWidgetBuilder.java @@ -0,0 +1,33 @@ +/** + * 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 . + */ +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 { + + /** {@inheritDoc} */ + @Override + public FunctionWidget build() { + return new FunctionWidget(this); + } +} \ No newline at end of file diff --git a/TULIP/src/lu/list/itis/dkd/tui/widget/corona/Corona.java b/TULIP/src/lu/list/itis/dkd/tui/widget/corona/Corona.java index 478dfeb..a176094 100644 --- a/TULIP/src/lu/list/itis/dkd/tui/widget/corona/Corona.java +++ b/TULIP/src/lu/list/itis/dkd/tui/widget/corona/Corona.java @@ -292,6 +292,33 @@ public abstract class Corona implements Comparable { 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. -- GitLab