diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/.ratings b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/.ratings index 451218a56f62f99e7ccf77d994d880985f85c591..534dfd93b12a4088a3e5ee58e43a34cfe451296c 100644 --- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/.ratings +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/.ratings @@ -1,9 +1,9 @@ ContextMenuUtil.java 405387151d45b09dffb3b6ba44f980313c8edcaf GREEN CurvedLinkLayoutedContentAnchorangeController.java 6d2b64c3d6c813ac001b1500ed0529ad6e561aaf YELLOW -EObjectDiagramController.java 9af59e8e586c8251d174108a2ce2fcdee5e75782 GREEN -EObjectEllipticResizableContentControllerBase.java 3494d4f0dcdff5eb35f22f0e21d04df81b32e494 GREEN +EObjectDiagramController.java 2b253941592ee25ead95223470f983f23ef9776f GREEN +EObjectEllipticResizableContentControllerBase.java 7c862a03b97d2f2cfdcc2fcee7434de2e1e257d2 GREEN EObjectModelChangeProvider.java f4b60cebb088a5c81ca92a41614e1a5d40030502 GREEN -EObjectRectangularResizableContentControllerBase.java f4a967591a60fadb20550ec3eaabccf240c9ec0d GREEN +EObjectRectangularResizableContentControllerBase.java 28a17bf87f6a7222d927bc1c6b80967cb14b5f03 GREEN KernelServiceBasedModelChangeProviderBase.java 8d1f8ef79ecd383ff74e5a2bbcf24345aabe70af GREEN LayoutModelChangeProvider.java b5449d02eaf39086909720c43e21bd061005fc9e GREEN LayoutedContentAnchorageController.java 9fc513a7404277514c730f7702d45588f2d81878 GREEN @@ -13,3 +13,4 @@ LayoutedEllipticResizableContentController.java 93bdeb7ecd5f7386724a9d7df5fff317 LayoutedLineLinkBendPointController.java f5fac4fe8e4b4c0259407acb6bfc80dbe9c3a1fb GREEN LayoutedLinkBendPointController.java 3203d946de233274934dca1bcd47bbdc1d0a3b13 GREEN LayoutedRectangularResizableContentController.java 3232d423572924363702898cf8ba240ce7042b65 GREEN +ModelElementFXEditorUIProviderBase.java b81bf7fc945d40f1f842876f07ba70799ab65f6d GREEN diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectDiagramController.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectDiagramController.java index 9af59e8e586c8251d174108a2ce2fcdee5e75782..2b253941592ee25ead95223470f983f23ef9776f 100644 --- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectDiagramController.java +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectDiagramController.java @@ -18,6 +18,8 @@ import static java.util.Objects.requireNonNull; import static org.fortiss.tooling.base.ui.editor.fx.controller.ContextMenuUtil.createDisplayMenu; import static org.fortiss.tooling.base.ui.editor.fx.controller.ContextMenuUtil.createElementCompositionContext; import static org.fortiss.tooling.base.ui.editor.fx.controller.ContextMenuUtil.createPrototypeMenu; +import static org.fortiss.tooling.base.ui.utils.FXDNDUtils.canCompose; +import static org.fortiss.tooling.base.ui.utils.FXDNDUtils.compose; import java.util.List; @@ -33,6 +35,7 @@ import org.fortiss.tooling.kernel.ui.service.IContextMenuService; import javafx.scene.Node; import javafx.scene.control.MenuItem; +import javafx.scene.input.Dragboard; /** * Diagram controller that uses the {@link IElementCompositorService} to create context menu @@ -41,7 +44,6 @@ import javafx.scene.control.MenuItem; * @author hoelzl */ public class EObjectDiagramController<T extends EObject> extends ControllerBase { - /** The model change provider. */ private final EObjectModelChangeProvider modelChangeProvider; @@ -85,4 +87,18 @@ public class EObjectDiagramController<T extends EObject> extends ControllerBase result.add(createDisplayMenu(getViewer())); return result; } + + /** {@inheritDoc} */ + @Override + public boolean handleExternalDNDDragOver(Dragboard db, DiagramCoordinate diagramLocation) { + double zoom = getViewer().getFeatures().getCurrentZoomFactor(); + return canCompose(db, diagramLocation, getModelElement(), true, zoom); + } + + /** {@inheritDoc} */ + @Override + public boolean handleExternalDNDDrop(Dragboard db, DiagramCoordinate diagramLocation) { + double zoom = getViewer().getFeatures().getCurrentZoomFactor(); + return compose(db, diagramLocation, getModelElement(), true, zoom); + } } diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectEllipticResizableContentControllerBase.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectEllipticResizableContentControllerBase.java index 3494d4f0dcdff5eb35f22f0e21d04df81b32e494..7c862a03b97d2f2cfdcc2fcee7434de2e1e257d2 100644 --- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectEllipticResizableContentControllerBase.java +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectEllipticResizableContentControllerBase.java @@ -17,6 +17,8 @@ import static java.lang.Math.max; import static java.util.Objects.requireNonNull; import static org.fortiss.tooling.base.ui.editor.fx.controller.ContextMenuUtil.createElementCompositionContext; import static org.fortiss.tooling.base.ui.editor.fx.controller.ContextMenuUtil.createPrototypeMenu; +import static org.fortiss.tooling.base.ui.utils.FXDNDUtils.canCompose; +import static org.fortiss.tooling.base.ui.utils.FXDNDUtils.compose; import java.util.List; @@ -40,6 +42,7 @@ import org.fortiss.tooling.kernel.ui.service.IModelElementHandlerService; import javafx.scene.Node; import javafx.scene.control.MenuItem; +import javafx.scene.input.Dragboard; import javafx.scene.input.MouseEvent; /** @@ -148,4 +151,18 @@ public abstract class EObjectEllipticResizableContentControllerBase<T extends EO public IClickController getClickController(Node node, DiagramCoordinate diagramLocation) { return openEditorDoubleClickController; } + + /** {@inheritDoc} */ + @Override + public boolean handleExternalDNDDragOver(Dragboard db, DiagramCoordinate diagramLocation) { + double zoom = getViewer().getFeatures().getCurrentZoomFactor(); + return canCompose(db, diagramLocation, getModelElement(), false, zoom); + } + + /** {@inheritDoc} */ + @Override + public boolean handleExternalDNDDrop(Dragboard db, DiagramCoordinate diagramLocation) { + double zoom = getViewer().getFeatures().getCurrentZoomFactor(); + return compose(db, diagramLocation, getModelElement(), false, zoom); + } } diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectRectangularResizableContentControllerBase.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectRectangularResizableContentControllerBase.java index f4a967591a60fadb20550ec3eaabccf240c9ec0d..28a17bf87f6a7222d927bc1c6b80967cb14b5f03 100644 --- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectRectangularResizableContentControllerBase.java +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/EObjectRectangularResizableContentControllerBase.java @@ -19,6 +19,8 @@ import static org.fortiss.tooling.base.layout.DefaultLayoutConstants.DEFAULT_SHA import static org.fortiss.tooling.base.layout.DefaultLayoutConstants.DEFAULT_SHAPE_MINIMUM_WIDTH; import static org.fortiss.tooling.base.ui.editor.fx.controller.ContextMenuUtil.createElementCompositionContext; import static org.fortiss.tooling.base.ui.editor.fx.controller.ContextMenuUtil.createPrototypeMenu; +import static org.fortiss.tooling.base.ui.utils.FXDNDUtils.canCompose; +import static org.fortiss.tooling.base.ui.utils.FXDNDUtils.compose; import java.util.List; @@ -46,6 +48,7 @@ import org.fortiss.tooling.kernel.ui.service.IModelElementHandlerService; import javafx.geometry.Dimension2D; import javafx.scene.Node; import javafx.scene.control.MenuItem; +import javafx.scene.input.Dragboard; import javafx.scene.input.MouseEvent; /** @@ -177,4 +180,18 @@ public abstract class EObjectRectangularResizableContentControllerBase<T extends public IClickController getClickController(Node node, DiagramCoordinate diagramLocation) { return openEditorDoubleClickController; } + + /** {@inheritDoc} */ + @Override + public boolean handleExternalDNDDragOver(Dragboard db, DiagramCoordinate diagramLocation) { + double zoom = getViewer().getFeatures().getCurrentZoomFactor(); + return canCompose(db, diagramLocation, getModelElement(), false, zoom); + } + + /** {@inheritDoc} */ + @Override + public boolean handleExternalDNDDrop(Dragboard db, DiagramCoordinate diagramLocation) { + double zoom = getViewer().getFeatures().getCurrentZoomFactor(); + return compose(db, diagramLocation, getModelElement(), false, zoom); + } } diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/ModelElementFXEditorUIProviderBase.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/ModelElementFXEditorUIProviderBase.java new file mode 100644 index 0000000000000000000000000000000000000000..b81bf7fc945d40f1f842876f07ba70799ab65f6d --- /dev/null +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/controller/ModelElementFXEditorUIProviderBase.java @@ -0,0 +1,73 @@ +/*-------------------------------------------------------------------------+ +| Copyright 2020 fortiss GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.base.ui.editor.fx.controller; + +import static org.fortiss.tooling.base.ui.editor.fx.controller.ContextMenuUtil.createPrototypeMenu; + +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.fortiss.tooling.base.model.element.IModelElement; +import org.fortiss.tooling.common.ui.javafx.control.treetableview.DynamicTreeTableUIProviderBase; +import org.fortiss.tooling.kernel.ui.extension.base.FXEditorBase; +import org.fortiss.tooling.kernel.ui.service.IModelElementHandlerService; + +import javafx.scene.Node; +import javafx.scene.control.ContextMenu; + +/** + * Base implementation for FX UIProvider for ModelElements. + * + * @author bayha + */ +public abstract class ModelElementFXEditorUIProviderBase<T extends IModelElement> + extends DynamicTreeTableUIProviderBase<T> { + + /** The editor used to post selection changes. */ + protected final FXEditorBase<?> editor; + + /** Constructor. */ + public ModelElementFXEditorUIProviderBase(FXEditorBase<?> editor) { + this.editor = editor; + } + + /** {@inheritDoc} */ + @Override + public Node getIconNode(IModelElement element, int column) { + if(element == null) { + return null; + } + return IModelElementHandlerService.getInstance().getFXIcon(element); + } + + /** {@inheritDoc} */ + @Override + public ContextMenu createContextMenu(IModelElement element, int column) { + if(element == null || column != 0) { + return null; + } + ContextMenu contextMenu = new ContextMenu(); + contextMenu.getItems().addAll(createPrototypeMenu(element, null)); + return contextMenu; + } + + /** {@inheritDoc} */ + @Override + public void select(IModelElement oldValue, IModelElement newValue) { + IStructuredSelection selection = + newValue == null ? StructuredSelection.EMPTY : new StructuredSelection(newValue); + editor.getSite().getSelectionProvider().setSelection(selection); + } +} diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/utils/.ratings b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/utils/.ratings index 673e0fc6505e31b30d19bf9937d831e8cbecb282..b6b09de379e179640e4e2959874cb52f189329a2 100644 --- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/utils/.ratings +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/utils/.ratings @@ -2,6 +2,7 @@ AbstractNameEditingSupport.java c57336a0e0da18711a1610ca667dfea76728807f GREEN ActionUtils.java 322f43d4f92f992daef8ac88eb0f9197c840c89b GREEN DragAndDropBaseUtils.java d375377f9124f6113b2a295e6b0e09ac8966e564 GREEN EllipseLayoutUIUtils.java 4dd9dbd96a45e8c455c019caa19e4a50f18336af GREEN +FXDNDUtils.java 6ce94e239e68f9e2b3cc0524b072606f4a120076 GREEN FontUtils.java a167a05bdaa8da9853705cc5134f30f6d81bc9f2 GREEN GCStateManager.java 983973a92376b5c757c1253b32e33d0666ccdf7b GREEN LWFXEditorUtils.java c624d3f0f6487b6d426b168dad048b2c39e71114 GREEN diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/utils/FXDNDUtils.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/utils/FXDNDUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..6ce94e239e68f9e2b3cc0524b072606f4a120076 --- /dev/null +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/utils/FXDNDUtils.java @@ -0,0 +1,122 @@ +/*-------------------------------------------------------------------------+ +| Copyright 2020 fortiss GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.base.ui.utils; + +import static org.fortiss.tooling.base.utils.LayoutModelElementFactory.createPoint; +import static org.fortiss.tooling.kernel.service.IPrototypeService.PROTOTYPE_DATA_FORMAT; + +import org.eclipse.emf.ecore.EObject; +import org.fortiss.tooling.base.dnd.ElementDropContext; +import org.fortiss.tooling.base.model.layout.Point; +import org.fortiss.tooling.common.ui.javafx.lwfxef.DiagramCoordinate; +import org.fortiss.tooling.kernel.extension.data.Prototype; +import org.fortiss.tooling.kernel.service.ICommandStackService; +import org.fortiss.tooling.kernel.service.IElementCompositorService; +import org.fortiss.tooling.kernel.service.IPrototypeService; + +import javafx.scene.input.Dragboard; + +/** + * Utility methods for JavaFX drag-and-drop. + * + * @author hoelzl + */ +public final class FXDNDUtils { + /** Returns whether element composition can be done via {@link IElementCompositorService}. */ + public static boolean canCompose(Dragboard db, EObject container) { + Prototype proto = extractPrototype(db); + if(proto != null) { + return IElementCompositorService.getInstance().canCompose(container, + proto.getPrototypeCopy(), null); + } + return false; + } + + /** Returns whether element composition can be done via {@link IElementCompositorService}. */ + public static boolean canCompose(Dragboard db, DiagramCoordinate location, EObject container, + boolean isRootContainer, double zoom) { + Prototype proto = extractPrototype(db); + if(proto != null) { + ElementDropContext ctx = + createElementDropContext(location, container, isRootContainer, zoom); + return IElementCompositorService.getInstance().canCompose(container, + proto.getPrototypeCopy(), ctx); + } + return false; + } + + /** Composes the elements using {@link IElementCompositorService}. */ + public static boolean compose(Dragboard db, EObject container) { + Prototype proto = extractPrototype(db); + if(proto != null) { + EObject copy = proto.getPrototypeCopy(); + return doElementComposition(container, copy, null); + } + return false; + } + + /** + * Composes the elements using {@link IElementCompositorService} creating an + * {@link ElementDropContext} for the given location, root element, and zoom factor. + */ + public static boolean compose(Dragboard db, DiagramCoordinate location, EObject container, + boolean isRootContainer, double zoom) { + Prototype proto = extractPrototype(db); + if(proto != null) { + EObject copy = proto.getPrototypeCopy(); + ElementDropContext ctx = + createElementDropContext(location, container, isRootContainer, zoom); + return doElementComposition(container, copy, ctx); + } + return false; + } + + /** Delegates to {@link IElementCompositorService} in order to compose the elements. */ + private static boolean doElementComposition(EObject container, EObject contained, + ElementDropContext context) { + IElementCompositorService ecs = IElementCompositorService.getInstance(); + if(ecs.canCompose(container, contained, context)) { + ICommandStackService.getInstance().runAsCommand(container, () -> { + ecs.compose(container, contained, context); + }); + return true; + } + return false; + } + + /** Creates the {@link ElementDropContext} containing the drop location. */ + private static ElementDropContext createElementDropContext(DiagramCoordinate location, + EObject container, boolean isRootContainer, double zoom) { + Point dcLocation = createPoint((int)location.getX(), (int)location.getY(), ""); + ElementDropContext ctx = + new ElementDropContext(container, dcLocation, isRootContainer, zoom); + return ctx; + } + + /** Extracts the prototype from the dragboard. */ + private static Prototype extractPrototype(Dragboard db) { + Object data = db.getContent(PROTOTYPE_DATA_FORMAT); + if(data instanceof String) { + return IPrototypeService.getInstance().getPrototypeByUniqueID((String)data); + } + return null; + } + + /** Constructor. */ + private FXDNDUtils() { + // prevent instantiation + } +} diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings index 4850e6d5cc854062f8760986309dc09fbbc41974..d62ac3736d877b3ebc3db9be04eecb910b812ca1 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings @@ -1,8 +1,8 @@ DynamicTreeContentProviderBase.java e801da995a1b6e5a1b757247c1638bafb6073e6d GREEN DynamicTreeItem.java 75dc5534b119ffdb3c10a65810c2a0f330b7955e GREEN -DynamicTreeTableUIProviderBase.java 7bfc1395283d3dc10026aff5e2e65df88d25f3a7 GREEN -DynamicTreeTableViewer.java 43757359b3071192ae79710bcbc0e9577bb6f62d GREEN -DynamicTreeUIProviderBase.java 56fe4df4577b35f1e5e6e4c4be189b706c852d52 GREEN -DynamicTreeViewer.java da5e24ae57777a482d8e12c8262513d8143bfa93 GREEN -DynamicTreeViewerBase.java 47124c847de322a0ae26eb7a114f85ce4bd02d7e GREEN +DynamicTreeTableUIProviderBase.java 75ddf3e91c08fd6a5853ab261593040d1039d774 GREEN +DynamicTreeTableViewer.java 431ac62cbd6ad7df25852fce1b5a62a05ba510e3 GREEN +DynamicTreeUIProviderBase.java e9b68607683de279d0cb8712a28dc131c5c33ece GREEN +DynamicTreeViewer.java e9f19d16a2a7e5a1b03b8a8b543453ac7eb6a051 GREEN +DynamicTreeViewerBase.java a2013538b62d86f6a09efdf2cd78babac2072484 GREEN IDoubleClickHandler.java 447f7769dead9a106b3ea3139ef0da51eb0b9a89 GREEN diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableUIProviderBase.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableUIProviderBase.java index 7bfc1395283d3dc10026aff5e2e65df88d25f3a7..75ddf3e91c08fd6a5853ab261593040d1039d774 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableUIProviderBase.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableUIProviderBase.java @@ -19,6 +19,7 @@ import javafx.scene.Node; import javafx.scene.control.ContextMenu; import javafx.scene.control.TreeTableCell; import javafx.scene.control.TreeTableColumn; +import javafx.scene.input.Dragboard; import javafx.util.Callback; /** @@ -59,6 +60,28 @@ public abstract class DynamicTreeTableUIProviderBase<T> { return null; } + /** + * @param item + * the tree element currently targeted by the drag location + * @param dragboard + * the current {@link Dragboard} + * @return whether the drag-over event succeeds (i.e. should be consumed). + */ + public boolean dragOver(T item, Dragboard dragboard) { + return false; + } + + /** + * @param element + * the element the content is dropped on + * @param dragboard + * the current {@link Dragboard} + * @return whether the drop event completed (i.e. should be consumed). + */ + public boolean dropClipboardContent(T element, Dragboard dragboard) { + return false; + } + /** * Returns whether the given column is editable. * diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableViewer.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableViewer.java index 43757359b3071192ae79710bcbc0e9577bb6f62d..431ac62cbd6ad7df25852fce1b5a62a05ba510e3 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableViewer.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableViewer.java @@ -15,12 +15,17 @@ *******************************************************************************/ package org.fortiss.tooling.common.ui.javafx.control.treetableview; +import static java.lang.Integer.MAX_VALUE; + import javafx.beans.property.SimpleObjectProperty; import javafx.scene.control.SelectionMode; import javafx.scene.control.TreeItem; import javafx.scene.control.TreeTableColumn; +import javafx.scene.control.TreeTableRow; import javafx.scene.control.TreeTableView; import javafx.scene.control.TreeTableView.TreeTableViewSelectionModel; +import javafx.scene.input.TransferMode; +import javafx.util.Callback; /** * A JavaFX {@link TreeTableView} based on an {@link DynamicTreeContentProviderBase} and @@ -43,7 +48,7 @@ public final class DynamicTreeTableViewer<T> extends DynamicTreeViewerBase<T> { public DynamicTreeTableViewer(TreeTableView<T> view, T root, boolean showRoot, int revealLevel, DynamicTreeContentProviderBase<T> contentProvider, DynamicTreeTableUIProviderBase<T> uiProvider) { - super(contentProvider); + super(view, contentProvider); this.uiProvider = uiProvider; // construct view this.view = view; @@ -51,6 +56,28 @@ public final class DynamicTreeTableViewer<T> extends DynamicTreeViewerBase<T> { view.setRoot(rootItem); view.setShowRoot(showRoot); view.setEditable(true); + view.setRowFactory(new Callback<TreeTableView<T>, TreeTableRow<T>>() { + @Override + public TreeTableRow<T> call(TreeTableView<T> param) { + final TreeTableRow<T> row = new TreeTableRow<T>(); + row.setOnDragOver(evt -> { + T item = row.getItem(); + if(uiProvider.dragOver(item, evt.getDragboard())) { + evt.acceptTransferModes(TransferMode.ANY); + evt.consume(); + } + }); + row.setOnDragDropped(evt -> { + T item = row.getItem(); + if(uiProvider.dropClipboardContent(item, evt.getDragboard())) { + evt.setDropCompleted(true); + evt.consume(); + } + }); + return row; + } + }); + TreeTableViewSelectionModel<T> selectionModel = view.getSelectionModel(); selectionModel.setSelectionMode(SelectionMode.MULTIPLE); selectionModel.selectedItemProperty().addListener((obs, oVal, nVal) -> { @@ -91,6 +118,16 @@ public final class DynamicTreeTableViewer<T> extends DynamicTreeViewerBase<T> { } } + /** Expands all items on all levels. */ + public void expandAllItems() { + TreeItem<T> root = view.getRoot(); + if(root == null) { + return; + } + + expandItem(root, MAX_VALUE); + } + /** * Adds a column to the table part of the view. The labels, context menus and icons are shown as * defined in the {@link DynamicTreeTableUIProviderBase}. @@ -98,8 +135,8 @@ public final class DynamicTreeTableViewer<T> extends DynamicTreeViewerBase<T> { public TreeTableColumn<T, String> addColumn(String headerLabel, int prefWidth) { int num = view.getColumns().size(); TreeTableColumn<T, String> column = new TreeTableColumn<>(headerLabel); - column.setPrefWidth(prefWidth); + column.setCellValueFactory(param -> { T data = param.getValue().getValue(); return new SimpleObjectProperty<String>(uiProvider.getLabel(data, num)); @@ -126,4 +163,12 @@ public final class DynamicTreeTableViewer<T> extends DynamicTreeViewerBase<T> { public TreeTableView<T> getControl() { return view; } + + /** {@inheritDoc} */ + @Override + protected T getSelectedObject() { + T value = view.getSelectionModel().getSelectedItem().getValue(); + + return value; + } } diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeUIProviderBase.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeUIProviderBase.java index 56fe4df4577b35f1e5e6e4c4be189b706c852d52..e9b68607683de279d0cb8712a28dc131c5c33ece 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeUIProviderBase.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeUIProviderBase.java @@ -15,10 +15,12 @@ package org.fortiss.tooling.common.ui.javafx.control.treetableview; import javafx.scene.Node; import javafx.scene.control.ContextMenu; +import javafx.scene.input.ClipboardContent; +import javafx.scene.input.Dragboard; /** * This UI provider is responsible to return the label, the icon, and the context menu for each cell - * in the {@link DynamicTreeViewer} based on the data object. + * in the {@link DynamicTreeViewer} based on the data object. It also handles drag start events. */ public abstract class DynamicTreeUIProviderBase<T> { /** @@ -47,4 +49,35 @@ public abstract class DynamicTreeUIProviderBase<T> { public ContextMenu createContextMenu(T element) { return null; } + + /** + * @param element + * the tree element, which was dragged + * @return the content of the clipboard or {@code null} if the drag should be ignored. + */ + public ClipboardContent getDragClipboardContent(T element) { + return null; + } + + /** + * @param item + * the tree element currently targeted by the drag location + * @param dragboard + * the current {@link Dragboard} + * @return whether the drag-over event succeeds (i.e. should be consumed). + */ + public boolean dragOver(T item, Dragboard dragboard) { + return false; + } + + /** + * @param element + * the element the content is dropped on + * @param dragboard + * the current {@link Dragboard} + * @return whether the drop event completed (i.e. should be consumed). + */ + public boolean dropClipboardContent(T element, Dragboard dragboard) { + return false; + } } diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeViewer.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeViewer.java index da5e24ae57777a482d8e12c8262513d8143bfa93..e9f19d16a2a7e5a1b03b8a8b543453ac7eb6a051 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeViewer.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeViewer.java @@ -16,15 +16,15 @@ package org.fortiss.tooling.common.ui.javafx.control.treetableview; import javafx.beans.value.ChangeListener; -import javafx.event.Event; -import javafx.event.EventDispatchChain; -import javafx.event.EventDispatcher; import javafx.scene.control.ContextMenu; import javafx.scene.control.TreeCell; import javafx.scene.control.TreeItem; import javafx.scene.control.TreeView; -import javafx.scene.input.MouseButton; +import javafx.scene.input.ClipboardContent; +import javafx.scene.input.DragEvent; +import javafx.scene.input.Dragboard; import javafx.scene.input.MouseEvent; +import javafx.scene.input.TransferMode; /** * A JavaFX {@link TreeView} based on a {@link DynamicTreeContentProviderBase} and a @@ -40,14 +40,12 @@ public final class DynamicTreeViewer<T> extends DynamicTreeViewerBase<T> { private final DynamicTreeUIProviderBase<T> uiProvider; /** The selection change listener. */ private ChangeListener<Object> selectionChangeListener = null; - /** The double click handler. */ - private IDoubleClickHandler doubleClickHandler; /** Constructor. */ public DynamicTreeViewer(TreeView<T> view, T root, boolean showRoot, int revealLevel, DynamicTreeContentProviderBase<T> contentProvider, DynamicTreeUIProviderBase<T> uiProvider) { - super(contentProvider); + super(view, contentProvider); this.uiProvider = uiProvider; // construct view this.view = view; @@ -119,11 +117,6 @@ public final class DynamicTreeViewer<T> extends DynamicTreeViewerBase<T> { this.selectionChangeListener = listener; } - /** Sets the double click handler. */ - public void setDoubleClickHandler(IDoubleClickHandler handler) { - this.doubleClickHandler = handler; - } - /** Configures the cell factory for the viewer. */ private void configureCellFactory() { view.setCellFactory(param -> { @@ -134,10 +127,17 @@ public final class DynamicTreeViewer<T> extends DynamicTreeViewerBase<T> { ContextMenu menu = null; if(!empty && item != null) { menu = uiProvider.createContextMenu(item); - EventDispatcher original = this.getEventDispatcher(); - this.setEventDispatcher(new DoubleClickEventDispatcher(original)); this.setText(uiProvider.getLabel(item)); this.setGraphic(uiProvider.getIconNode(item)); + this.setOnDragDetected(evt -> { + dragDetected(evt, this, item); + }); + this.setOnDragOver(evt -> { + dragOver(evt, item); + }); + this.setOnDragDropped(evt -> { + dragDropped(evt, item); + }); } else { this.setText(null); this.setGraphic(null); @@ -149,6 +149,28 @@ public final class DynamicTreeViewer<T> extends DynamicTreeViewerBase<T> { }); } + /** Called when an item in the tree is dragged. */ + private void dragDetected(MouseEvent evt, TreeCell<T> cell, T item) { + ClipboardContent cbContent = uiProvider.getDragClipboardContent(item); + if(cbContent != null) { + Dragboard db = cell.startDragAndDrop(TransferMode.ANY); + db.setContent(cbContent); + evt.consume(); + } + } + + /** Gives the current drag-over event to the UI provider. */ + private void dragOver(DragEvent evt, T item) { + if(uiProvider.dragOver(item, evt.getDragboard())) { + evt.consume(); + } + } + + /** Gives the completed drop gesture to the UI provider. */ + private void dragDropped(DragEvent evt, T item) { + uiProvider.dropClipboardContent(item, evt.getDragboard()); + } + /** Expands the tree to the given item. */ public void expandItem(TreeItem<T> item) { while(item.getParent() != null) { @@ -169,6 +191,19 @@ public final class DynamicTreeViewer<T> extends DynamicTreeViewerBase<T> { } } + /** Expands the whole tree. */ + public void expandAllItems() { + expandAllItems(rootItem); + } + + /** Recursively expands the whole tree. */ + private void expandAllItems(TreeItem<T> item) { + item.setExpanded(true); + for(TreeItem<T> child : item.getChildren()) { + expandAllItems(child); + } + } + /** Returns the underlying {@link TreeView}. */ public TreeView<T> getControl() { return view; @@ -179,37 +214,15 @@ public final class DynamicTreeViewer<T> extends DynamicTreeViewerBase<T> { return uiProvider; } - /** - * Customized event dispatcher to fix double-click behavior. This prevents opening/closing of - * tree items with double click listeners assigned. - */ - private class DoubleClickEventDispatcher implements EventDispatcher { - /** The original event dispatcher. */ - private final EventDispatcher original; + /** {@inheritDoc} */ + @Override + protected Object getSelectedObject() { + DynamicTreeItem<T> item = (DynamicTreeItem<T>)view.getSelectionModel().getSelectedItem(); - /** Constructor. */ - public DoubleClickEventDispatcher(EventDispatcher original) { - this.original = original; + if(item != null) { + return item.getValue(); } - /** {@inheritDoc} */ - @Override - public Event dispatchEvent(Event event, EventDispatchChain tail) { - if(event instanceof MouseEvent) { - MouseEvent mevt = (MouseEvent)event; - if(mevt.getButton() == MouseButton.PRIMARY && mevt.getClickCount() >= 2) { - if(mevt.getEventType().equals(MouseEvent.MOUSE_CLICKED) && - doubleClickHandler != null) { - DynamicTreeItem<T> item = - (DynamicTreeItem<T>)view.getSelectionModel().getSelectedItem(); - if(item != null) { - doubleClickHandler.doubleClicked(item.getValue()); - } - } - event.consume(); - } - } - return original.dispatchEvent(event, tail); - } + return null; } } diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeViewerBase.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeViewerBase.java index 47124c847de322a0ae26eb7a114f85ce4bd02d7e..a2013538b62d86f6a09efdf2cd78babac2072484 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeViewerBase.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeViewerBase.java @@ -15,20 +15,91 @@ *******************************************************************************/ package org.fortiss.tooling.common.ui.javafx.control.treetableview; +import javafx.event.Event; +import javafx.event.EventDispatchChain; +import javafx.event.EventDispatcher; +import javafx.scene.control.Control; +import javafx.scene.control.TreeItem; +import javafx.scene.input.MouseButton; +import javafx.scene.input.MouseEvent; + /** * Base class for {@link DynamicTreeViewer} and {@link DynamicTreeTableViewer}. */ abstract class DynamicTreeViewerBase<T> { + /** The double click handler. */ + private IDoubleClickHandler doubleClickHandler; + + /** The double click event dispatcher. */ + protected DoubleClickEventDispatcher doubleClickEventDispatcher; + /** The content provider implementation. */ private final DynamicTreeContentProviderBase<T> contentProvider; /** Constructor. */ - public DynamicTreeViewerBase(DynamicTreeContentProviderBase<T> contentProvider) { + public DynamicTreeViewerBase(Control control, + DynamicTreeContentProviderBase<T> contentProvider) { this.contentProvider = contentProvider; + + setupEventDispatcher(control); + } + + /** Creates and installs the EventDispatcher. Might be overwritten to change behavior. */ + protected void setupEventDispatcher(Control control) { + EventDispatcher original = control.getEventDispatcher(); + control.setEventDispatcher(new DoubleClickEventDispatcher(original)); } /** Returns the content provider. */ public final DynamicTreeContentProviderBase<T> getContentProvider() { return contentProvider; } + + /** + * Customized event dispatcher to fix double-click behavior. This prevents opening/closing of + * tree items with double click listeners assigned. + */ + private class DoubleClickEventDispatcher implements EventDispatcher { + /** The original event dispatcher. */ + private final EventDispatcher original; + + /** Constructor. */ + public DoubleClickEventDispatcher(EventDispatcher original) { + this.original = original; + } + + /** {@inheritDoc} */ + @Override + public Event dispatchEvent(Event event, EventDispatchChain tail) { + if(event instanceof MouseEvent) { + MouseEvent mevt = (MouseEvent)event; + if(mevt.getButton() == MouseButton.PRIMARY && mevt.getClickCount() >= 2) { + if(mevt.getEventType().equals(MouseEvent.MOUSE_CLICKED) && + doubleClickHandler != null) { + Object item = getSelectedObject(); + if(item != null) { + doubleClickHandler.doubleClicked(item); + } + } + event.consume(); + } + } + return original.dispatchEvent(event, tail); + } + } + + /** Sets the double click handler. */ + public void setDoubleClickHandler(IDoubleClickHandler handler) { + this.doubleClickHandler = handler; + } + + /** + * Retrieves the currently selected {@link Object} from this viewer. + * + * Note: This usually is not e.g. the {@link TreeItem} or similar, but the model object, that is + * represented by it. Usually this will be some EObject. + * + * @return The currently selected {@link Object}. + */ + protected abstract Object getSelectedObject(); } diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/.ratings b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/.ratings index c412a38af52a0cbcdfa85489641d51605592d9d2..40604380943c328a66a0fe98428016395dcf0b15 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/.ratings +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/.ratings @@ -1,6 +1,6 @@ DiagramCoordinate.java 6b00aec99054d4cd19003a72bd4e5e774ac6a641 GREEN DiagramLayers.java 155cbb47a5f0aaa0025320ae607e6777f3a2d2e8 GREEN -DiagramViewer.java e7c550be6443f798ba9399a35ab3059033a33e59 RED +DiagramViewer.java a96338d3d8e043564eb857920ade45f6e2d4ac18 GREEN DiagramViewerDefaultTags.java 6230763252409c60009ab8887b4ef582cf883229 GREEN DiagramViewerFeatures.java 31e3fb61f915b0d8695005b083c47ce1c5be0b05 GREEN DiagramViewerSelection.java e833f592543bc97077907d980a39b123fc4044e6 GREEN @@ -8,5 +8,5 @@ EDragGesture.java 5cfa098d3877db11981c2750e5e103156d62fc5e GREEN FeedbackChange.java b088fa89af648f1674f2f9c1f7f99d585ce801ca GREEN GridCanvasVisual.java 734027d56af342cd01ff445ba9347b8dbb6c83c2 GREEN MVCBundleManager.java 2b4ab114c55b30a3d98d7135458f8f3ddd244d58 GREEN -MouseState.java ff90af6d1cca427ef6f3fded76367b535120a5df GREEN +MouseState.java 3d9993f799d5d74bc74ac03b46e4a1857c4d267e GREEN SVGExporter.java 2211f06d81c7b0523ae52dc832410a76875a9e07 GREEN diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/DiagramViewer.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/DiagramViewer.java index e7c550be6443f798ba9399a35ab3059033a33e59..a96338d3d8e043564eb857920ade45f6e2d4ac18 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/DiagramViewer.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/DiagramViewer.java @@ -71,6 +71,8 @@ import javafx.scene.shape.Rectangle; * for the purpose of source code size reduction. */ public class DiagramViewer { + /** The default dash stroke pattern. */ + private final Double[] DEFAULT_DASH_STROKE_PATTERN = new Double[] {15.0, 5.0}; /** The bundle manager helper class reference. */ private final MVCBundleManager viewerManager; /** The feature state helper class reference. */ @@ -118,8 +120,7 @@ public class DiagramViewer { // selection feedback rectangle mouseDragRectangle.setFill(Color.TRANSPARENT); mouseDragRectangle.setStroke(Color.ORANGERED); - // TODO (SB): Magic constant - mouseDragRectangle.getStrokeDashArray().addAll(15.0, 5.0); + mouseDragRectangle.getStrokeDashArray().addAll(DEFAULT_DASH_STROKE_PATTERN); mouseDragRectangle.setMouseTransparent(true); // viewer pane viewerPane = new Pane(); diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/MouseState.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/MouseState.java index ff90af6d1cca427ef6f3fded76367b535120a5df..3d9993f799d5d74bc74ac03b46e4a1857c4d267e 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/MouseState.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/MouseState.java @@ -31,9 +31,11 @@ import org.fortiss.tooling.common.ui.javafx.lwfxef.visual.IVisual; import javafx.event.EventHandler; import javafx.scene.Cursor; import javafx.scene.Node; +import javafx.scene.input.DragEvent; import javafx.scene.input.KeyEvent; import javafx.scene.input.MouseButton; import javafx.scene.input.MouseEvent; +import javafx.scene.input.TransferMode; /** * Class for monitoring mouse operations including clicking, dragging and linking @@ -324,6 +326,50 @@ public final class MouseState { } }; + /** The drag over event handler. */ + private final EventHandler<DragEvent> dragOverHandler = new EventHandler<DragEvent>() { + @Override + public void handle(DragEvent event) { + if(!nodesToBundleMap.containsKey(event.getSource())) { + return; + } + // wild cast works, since source is in nodesMap + Node source = (Node)event.getSource(); + IMVCBundle bundle = nodesToBundleMap.get(source); + IController ctrl = bundle.getController(); + lastMouseLocation = + viewer.convertEventToDiagramCoordinates(event.getX(), event.getY(), source); + if(ctrl != null) { + if(ctrl.handleExternalDNDDragOver(event.getDragboard(), lastMouseLocation)) { + event.acceptTransferModes(TransferMode.ANY); + event.consume(); + } + } + } + }; + + /** The drop event handler. */ + private final EventHandler<DragEvent> dropHandler = new EventHandler<DragEvent>() { + @Override + public void handle(DragEvent event) { + if(!nodesToBundleMap.containsKey(event.getSource())) { + return; + } + // wild cast works, since source is in nodesMap + Node source = (Node)event.getSource(); + IMVCBundle bundle = nodesToBundleMap.get(source); + IController ctrl = bundle.getController(); + lastMouseLocation = + viewer.convertEventToDiagramCoordinates(event.getX(), event.getY(), source); + if(ctrl != null) { + if(ctrl.handleExternalDNDDrop(event.getDragboard(), lastMouseLocation)) { + event.setDropCompleted(true); + event.consume(); + } + } + } + }; + /** Registers the mouse listeners on the given node. */ /* package */ void registerMouseListeners(Node node, IMVCBundle mvcb) { node.setOnMousePressed(mousePressedHandler); @@ -337,11 +383,15 @@ public final class MouseState { node.setOnMouseDragReleased(mouseDragCompletedHandler); node.setOnMouseMoved(mouseMotionHandler); node.setOnKeyReleased(keyEventHandler); + node.setOnDragOver(dragOverHandler); + node.setOnDragDropped(dropHandler); nodesToBundleMap.put(node, mvcb); } /** Unregisters the mouse listeners from the given node. */ /* package */ void unregisterMouseListeners(Node node) { + node.setOnDragDropped(null); + node.setOnDragOver(null); node.setOnKeyReleased(null); node.setOnMouseMoved(null); node.setOnMouseDragReleased(null); diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/controller/.ratings b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/controller/.ratings index cfa9cb5656d6c4b10625c7f4b9a179d3c7efe731..d3f2c8335a00977d02264f0c38fcf2724f7d7904 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/controller/.ratings +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/controller/.ratings @@ -1,5 +1,5 @@ IClickController.java c0270e99d918aef14612d46f3e84905d3a6bdd8c GREEN -IController.java 6ba069977e7588f97187916c23a0e37f7cb91059 GREEN +IController.java 443fe97dae2f8142e9ebc6df3267b505444c4bbe GREEN IControllerFactory.java 85b86eda643489f2a03454eae5383915ecf27f83 GREEN IDragController.java c1f311d2ae9ed684c8a7cd85e9ed1f85e79658d1 GREEN IKeyPressController.java dc8fe2a7c441866122e8c7b3114fd12d17f0b051 GREEN diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/controller/IController.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/controller/IController.java index 6ba069977e7588f97187916c23a0e37f7cb91059..443fe97dae2f8142e9ebc6df3267b505444c4bbe 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/controller/IController.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/controller/IController.java @@ -23,6 +23,7 @@ import org.fortiss.tooling.common.ui.javafx.lwfxef.mvc.MVCBundleTag; import javafx.scene.Cursor; import javafx.scene.Node; import javafx.scene.control.MenuItem; +import javafx.scene.input.Dragboard; /** * Interface for controllers which are informed about gestures or clicks and provide context menus @@ -58,6 +59,20 @@ public interface IController extends IMVCBundlePart { */ List<MenuItem> contextMenuContributions(Node node, DiagramCoordinate diagramLocation); + /** + * Handles the external DND drag over event. The framework calls this method when a + * {@link Node#setOnDragOver(javafx.event.EventHandler)} event occurred at the given location. + * This method should return {@code true} if the event was processed. + */ + boolean handleExternalDNDDragOver(Dragboard db, DiagramCoordinate diagramLocation); + + /** + * Handles the external DND drop event. The framework calls this method when a + * {@link Node#setOnDragDropped(javafx.event.EventHandler)} event occurred at the given + * location. This method should return {@code true} if the drop event was completed. + */ + boolean handleExternalDNDDrop(Dragboard db, DiagramCoordinate diagramLocation); + /** * Returns whether this bundle represents a possible link target. If this method returns * {@code false} this bundle is considered neither when a new link gesture is started nor diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/controller/base/.ratings b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/controller/base/.ratings index 6ffed36a00066011648fa84b53763f2b15a33159..f86b4498f6352f1ac31698af761319730ac39bb2 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/controller/base/.ratings +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/controller/base/.ratings @@ -1,11 +1,11 @@ AnchorageContentControllerBase.java da56b10cbf2711b5da69f0b59f43eacbe54f4eea GREEN ClickControllerBase.java 8e5861ed5f9318008ad0fdd5497ed320cd5bd647 GREEN ContentAnchorageMoveControllerBase.java c18e7915ce23e124757f5b736086ecc46694800a GREEN -ControllerBase.java 309e9ee3f3a255b5a06fed8f1b4d4ec8bf88f101 GREEN +ControllerBase.java c74e905a2b47dbf9b6443d94a877f1a9e56ba031 GREEN DefaultDiagramController.java 0e083b89a08f63967102a384d66ebc1d64d203af GREEN DelegatingContentAnchorageController.java 2e3b1b4e14402a3503233f816b21ef3e4aa09edc GREEN DragControllerBase.java b15ff874304f679fe494d85f57cc8cbe4d0d1d15 GREEN DraggingUtils.java 95117e2ea4c36b6c6a31f8088bb95b484e0e6612 GREEN -LinkControllerBase.java 392cb79cb42e9f878c665d47053b0795c3768603 GREEN +LinkControllerBase.java 4b6239c10cbbc5a2226615f7c6775f11adf226ef GREEN MoveControllerBase.java 38d632e31f5e27d112ecdd4933e3a331378180d0 GREEN ResizableContentControllerBase.java 898500d389b035f8138308d496d2d24be501c719 GREEN diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/controller/base/ControllerBase.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/controller/base/ControllerBase.java index 309e9ee3f3a255b5a06fed8f1b4d4ec8bf88f101..c74e905a2b47dbf9b6443d94a877f1a9e56ba031 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/controller/base/ControllerBase.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/controller/base/ControllerBase.java @@ -32,6 +32,7 @@ import org.fortiss.tooling.common.ui.javafx.lwfxef.mvc.impl.MVCBundlePartBase; import javafx.scene.Cursor; import javafx.scene.Node; import javafx.scene.control.MenuItem; +import javafx.scene.input.Dragboard; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.input.MouseEvent; @@ -104,6 +105,18 @@ public abstract class ControllerBase extends MVCBundlePartBase implements IContr return true; } + /** {@inheritDoc} */ + @Override + public boolean handleExternalDNDDragOver(Dragboard db, DiagramCoordinate diagramLocation) { + return false; + } + + /** {@inheritDoc} */ + @Override + public boolean handleExternalDNDDrop(Dragboard db, DiagramCoordinate diagramLocation) { + return false; + } + /** {@inheritDoc} */ @Override public IDragController getDragController(EDragGesture gesture, Node node, diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/controller/base/LinkControllerBase.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/controller/base/LinkControllerBase.java index 392cb79cb42e9f878c665d47053b0795c3768603..4b6239c10cbbc5a2226615f7c6775f11adf226ef 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/controller/base/LinkControllerBase.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/controller/base/LinkControllerBase.java @@ -42,6 +42,7 @@ import javafx.geometry.Point2D; import javafx.scene.Cursor; import javafx.scene.Node; import javafx.scene.control.MenuItem; +import javafx.scene.input.Dragboard; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.input.MouseEvent; @@ -467,4 +468,16 @@ public abstract class LinkControllerBase extends MVCBundlePartBase implements IC /** Returns the number of bend-points in the model. */ protected abstract int getNumerOfBendPoints(); + + /** {@inheritDoc} */ + @Override + public boolean handleExternalDNDDragOver(Dragboard db, DiagramCoordinate diagramLocation) { + return false; + } + + /** {@inheritDoc} */ + @Override + public boolean handleExternalDNDDrop(Dragboard db, DiagramCoordinate diagramLocation) { + return false; + } } diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/base/.ratings b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/base/.ratings index f25afc4fc869edb72d824531a0f042e3a2f447e7..5fbb3ba7a06a40fa2129b9a08eb806278183037d 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/base/.ratings +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/base/.ratings @@ -1,6 +1,6 @@ ContentAnchorageVisualBase.java 6722629a940e9f8d973d2176bc3855932d7fa35a GREEN -ContentVisualBase.java d232c6cb7bc54b2430379379eb2985f5a2e12cd3 RED +ContentVisualBase.java 6c9c508803874db2f5ffffb723c1df5664827a5d GREEN DiagramAnchorageVisualBase.java 05c235152bc79187f0fc9b041435da7968654a78 GREEN LinkVisualBase.java 909b933b38b7651cac901d767115e173983bef26 GREEN MVCBundlePartWithEffectsBase.java 6f6fbbb065950ad3acd4dc1fbfdd1348874e51d2 GREEN -VisualBase.java 8d6e74d5c74703dad12847cd5c913fa72707a84a RED +VisualBase.java 276f4f5a881bd3a89c312522f9006e6f0cfd57c9 GREEN diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/base/ContentVisualBase.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/base/ContentVisualBase.java index d232c6cb7bc54b2430379379eb2985f5a2e12cd3..6c9c508803874db2f5ffffb723c1df5664827a5d 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/base/ContentVisualBase.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/base/ContentVisualBase.java @@ -41,7 +41,6 @@ public abstract class ContentVisualBase extends VisualBase implements IContentVi protected final Text text = new Text(); /** The icon of this visual. */ protected final ImageView icon = new ImageView(); - // TODO (SB): Magic constant /** The expanded / collapsed indicator widget. */ protected final ExpandCollapseWidget expandCollapseWidget = new ExpandCollapseWidget(0, 0, 20, 20, 3); diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/base/VisualBase.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/base/VisualBase.java index 8d6e74d5c74703dad12847cd5c913fa72707a84a..276f4f5a881bd3a89c312522f9006e6f0cfd57c9 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/base/VisualBase.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/base/VisualBase.java @@ -49,6 +49,11 @@ import javafx.scene.text.TextAlignment; * This implementation provides a simple {@link DropShadow} hover effect and a hover label. */ public abstract class VisualBase extends MVCBundlePartWithEffectsBase implements IVisual { + /** The default drop shadow radius. */ + private static final double DEFAULT_DROP_SHADOW_RAIDUS = 10; + /** The default drop shadow radius. */ + private static final double DEFAULT_DROP_SHADOW_OFFSET = 3; + /** The visible shape of this visual. */ private final Shape visualShape; /** The invisible hit area of this visual. */ @@ -85,8 +90,8 @@ public abstract class VisualBase extends MVCBundlePartWithEffectsBase implements protected void createHoverEffect(DiagramLayers layers) { Color shadow = getHoverShadowColor(); if(shadow != null && visualShape != null) { - // TODO (SB): Magic constant - visualShape.setEffect(new DropShadow(10, 3, 3, shadow)); + visualShape.setEffect(new DropShadow(DEFAULT_DROP_SHADOW_RAIDUS, + DEFAULT_DROP_SHADOW_OFFSET, DEFAULT_DROP_SHADOW_OFFSET, shadow)); } // handle hover text String text = getHoverText(); diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/elliptic/.ratings b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/elliptic/.ratings index 1b4320c713efe1645fba333acaa27c6fb6bf4629..d28fe8e0fb9f0db1545183c5cbbfaffb8127180f 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/elliptic/.ratings +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/elliptic/.ratings @@ -1,6 +1,6 @@ -CircularContentAnchorageVisualBase.java e1d3f982239beb38120c7eda6ecf319ab2779f9c RED +CircularContentAnchorageVisualBase.java c72fb8b95ef1e3650378f1c580c9362ebb852f46 GREEN CircularContentVisualBase.java cc3caea328e36e90069b915e413c8e7e9522a939 GREEN -CircularDiagramAnchorageVisualBase.java 7a3b92fb1b135c218b9a5e16506acfc74a6b5468 YELLOW +CircularDiagramAnchorageVisualBase.java 7a3b92fb1b135c218b9a5e16506acfc74a6b5468 GREEN CurveLinkVisualBase.java 5ce3086769004a9eb6800d7eb58379d831ff74b1 GREEN CurveSegment.java 0e7f70e9526a74aaec2bec4f4fc16295521cf5f2 GREEN EllipticBorderLocation.java 1e9b3d42c7fcd5495004fb30b0c499096a839967 GREEN diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/elliptic/CircularContentAnchorageVisualBase.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/elliptic/CircularContentAnchorageVisualBase.java index e1d3f982239beb38120c7eda6ecf319ab2779f9c..c72fb8b95ef1e3650378f1c580c9362ebb852f46 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/elliptic/CircularContentAnchorageVisualBase.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/elliptic/CircularContentAnchorageVisualBase.java @@ -26,6 +26,9 @@ import javafx.scene.shape.Circle; /** Base class for {@link IContentAnchorageVisual}s depicted as circles. */ public abstract class CircularContentAnchorageVisualBase extends ContentAnchorageVisualBase { + /** The default insets. */ + private static final double DEFAULT_INSET = 2; + /** Constructor. */ public CircularContentAnchorageVisualBase(IContentAnchorageMVCBundle mvcb) { super(mvcb, new Circle(), new Circle()); @@ -84,8 +87,7 @@ public abstract class CircularContentAnchorageVisualBase extends ContentAnchorag /** Returns the insets of the filled circle subtracted from {@link #getDimensions()}. */ protected double getInset() { - // TODO (SB): Magic constant - return 2; + return DEFAULT_INSET; } /** {@inheritDoc} */ diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/rectangular/.ratings b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/rectangular/.ratings index 3c07cda2d566de786499df2e878426974facd923..b2bd51c666f1d44fe1c509afafc7d3663c9faebd 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/rectangular/.ratings +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/rectangular/.ratings @@ -1,9 +1,9 @@ -DiamondContentVisualBase.java de349d41b84b2063f74c03ff5ad7290855e997f7 RED +DiamondContentVisualBase.java a81e76e85706ad38b6c22bbcd1cc5a5696737e3d GREEN LineLinkGraph.java 85a06a553f88f7b9fb4bd9c06411725d9fb160fc GREEN -LineLinkVisualBase.java 5529031f89a96ad0322f011e89dad1ece785bc03 RED +LineLinkVisualBase.java 74968c18bb68859bc795ed9a3b0693d1787e0806 GREEN LineSegment.java a8658ec5bcd930d417a148861831b9ebb70bb37d GREEN RectangularBorderLocation.java 824472c353534d1094ae4f735a30a231b885f050 GREEN RectangularContentAnchorageVisualBase.java 39981dc29cac42d77c6ffe855ecc8ccad1689230 GREEN -RectangularContentVisualBase.java aee9ac3dbd53ce89539252d9984ed103d955be2f RED +RectangularContentVisualBase.java aeeda282f330180b1f339e3230810eccea2e7e7b GREEN RectangularDiagramAnchorageVisualBase.java 1259d6d110becca9ae02c754036c6693f00de683 GREEN -RhomboidContentVisualBase.java 0c3820cbfd3763c3cb6b1a0cba5cc71d8eecea73 RED +RhomboidContentVisualBase.java 7f4d72e17d58a950814d76509a6d6402bbd7bba7 GREEN diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/rectangular/DiamondContentVisualBase.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/rectangular/DiamondContentVisualBase.java index de349d41b84b2063f74c03ff5ad7290855e997f7..a81e76e85706ad38b6c22bbcd1cc5a5696737e3d 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/rectangular/DiamondContentVisualBase.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/rectangular/DiamondContentVisualBase.java @@ -34,6 +34,9 @@ import javafx.scene.shape.PathElement; /** Base class for {@link ContentVisualBase content visuals} depicted by a diamond shape. */ public abstract class DiamondContentVisualBase extends ContentVisualBase { + /** The default text anchor location. */ + private static final double DEFAULT_TEXTANCHOR_DIVIDER = 5; + /** Constructor. */ public DiamondContentVisualBase(IContentMVCBundle mvcb) { super(mvcb, new Path(), new Path()); @@ -190,7 +193,7 @@ public abstract class DiamondContentVisualBase extends ContentVisualBase { @Override protected DiagramCoordinate getTextAnchorLocation() { DiagramCoordinate textAnchorLocation = super.getTextAnchorLocation(); - // TODO (SB): Magic constant - return textAnchorLocation.add(getCurrentBounds().getWidth() / 5, 0); + return textAnchorLocation.add(getCurrentBounds().getWidth() / DEFAULT_TEXTANCHOR_DIVIDER, + 0); } } diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/rectangular/LineLinkVisualBase.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/rectangular/LineLinkVisualBase.java index 5529031f89a96ad0322f011e89dad1ece785bc03..74968c18bb68859bc795ed9a3b0693d1787e0806 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/rectangular/LineLinkVisualBase.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/rectangular/LineLinkVisualBase.java @@ -36,6 +36,8 @@ import javafx.scene.paint.Paint; /** Base class for {@link LinkVisualBase link visuals} with straight lines. */ public abstract class LineLinkVisualBase extends LinkVisualBase { + /** The default arrow length. */ + private static final double DEFAULT_ARROW_LENGTH = 10.0; /** Stores the visual segments. */ private final List<LineSegment> segments = new LinkedList<>(); /** Flag storing if the lines have been added. */ @@ -339,8 +341,7 @@ public abstract class LineLinkVisualBase extends LinkVisualBase { /** Returns the length of the arrow. */ protected double getArrowLength() { - // TODO (SB): Magic constant - return 10; + return DEFAULT_ARROW_LENGTH; } /** Returns the width of the invisible selection line. */ diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/rectangular/RectangularContentVisualBase.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/rectangular/RectangularContentVisualBase.java index aee9ac3dbd53ce89539252d9984ed103d955be2f..aeeda282f330180b1f339e3230810eccea2e7e7b 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/rectangular/RectangularContentVisualBase.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/rectangular/RectangularContentVisualBase.java @@ -28,9 +28,11 @@ import javafx.scene.Node; import javafx.scene.paint.Color; import javafx.scene.shape.Rectangle; -// TODO (SB): Check potential code duplication with RectangularContentVisualBase (dragGestureHitTest) /** Base class for {@link ContentVisualBase content visuals} depicted by rectangles. */ public abstract class RectangularContentVisualBase extends ContentVisualBase { + /** The default corner arc. */ + private static final Dimension2D DEFAULT_CORNER_ARC = new Dimension2D(15, 15); + /** Constructor. */ public RectangularContentVisualBase(IContentMVCBundle mvcb) { super(mvcb, new Rectangle(), new Rectangle()); @@ -99,39 +101,15 @@ public abstract class RectangularContentVisualBase extends ContentVisualBase { /** Returns the dimensions of the corner arcs. */ protected Dimension2D getCornerArcDimensions() { - // TODO (SB): Magic constant - return new Dimension2D(15, 15); + return DEFAULT_CORNER_ARC; } /** {@inheritDoc} */ @Override protected EDragGesture dragGestureHitTest(Node node, DiagramCoordinate diagramLocation) { if(node == getHitAreaShape()) { - double x = diagramLocation.getLocalX(node); - double y = diagramLocation.getLocalY(node); - double l = getHitAreaStartLinkSize(); - double r = getHitAreaResizeSize(); - Bounds bounds = node.getBoundsInLocal(); - // check for move area - double inset = l + r; - Rectangle2D moveArea = new Rectangle2D(inset, inset, bounds.getWidth() - 2 * inset, - bounds.getHeight() - 2 * inset); - if(moveArea.contains(x, y)) { - return EDragGesture.MOVE; - } - if(x < l || y < l || x > bounds.getWidth() - l || y > bounds.getHeight() - l) { - return EDragGesture.NEW_LINK; - } - if(x > bounds.getWidth() - inset && y >= l && y <= bounds.getHeight() - inset) { - return EDragGesture.RESIZE_H; - } - if(y > bounds.getHeight() - inset && x >= l && x <= bounds.getWidth() - inset) { - return EDragGesture.RESIZE_V; - } - if(x > bounds.getWidth() - inset && y > bounds.getHeight() - inset) { - return EDragGesture.RESIZE_VH; - } - return EDragGesture.NONE; + return getRectangularShapeDragGesture(node, diagramLocation, getHitAreaStartLinkSize(), + getHitAreaResizeSize()); } if(node == getVisualShape() || node == text) { return EDragGesture.MOVE; @@ -139,6 +117,35 @@ public abstract class RectangularContentVisualBase extends ContentVisualBase { return EDragGesture.NONE; } + /** Computes the {@link EDragGesture} for the rectangular shape case. */ + /* package */ static EDragGesture getRectangularShapeDragGesture(Node node, + DiagramCoordinate diagramLocation, double startLinkSize, double resizeAreaSize) { + double x = diagramLocation.getLocalX(node); + double y = diagramLocation.getLocalY(node); + Bounds bounds = node.getBoundsInLocal(); + // check for move area + double inset = startLinkSize + resizeAreaSize; + Rectangle2D moveArea = new Rectangle2D(inset, inset, bounds.getWidth() - 2 * inset, + bounds.getHeight() - 2 * inset); + if(moveArea.contains(x, y)) { + return EDragGesture.MOVE; + } + if(x < startLinkSize || y < startLinkSize || x > bounds.getWidth() - startLinkSize || + y > bounds.getHeight() - startLinkSize) { + return EDragGesture.NEW_LINK; + } + if(x > bounds.getWidth() - inset && y >= startLinkSize && y <= bounds.getHeight() - inset) { + return EDragGesture.RESIZE_H; + } + if(y > bounds.getHeight() - inset && x >= startLinkSize && x <= bounds.getWidth() - inset) { + return EDragGesture.RESIZE_V; + } + if(x > bounds.getWidth() - inset && y > bounds.getHeight() - inset) { + return EDragGesture.RESIZE_VH; + } + return EDragGesture.NONE; + } + /** Returns the visual rectangle shape. */ protected final Rectangle getVisualRectangleShape() { // wild cast works: see constructor diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/rectangular/RhomboidContentVisualBase.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/rectangular/RhomboidContentVisualBase.java index 0c3820cbfd3763c3cb6b1a0cba5cc71d8eecea73..7f4d72e17d58a950814d76509a6d6402bbd7bba7 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/rectangular/RhomboidContentVisualBase.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/lwfxef/visual/rectangular/RhomboidContentVisualBase.java @@ -10,6 +10,7 @@ package org.fortiss.tooling.common.ui.javafx.lwfxef.visual.rectangular; import static org.fortiss.tooling.common.ui.javafx.lwfxef.visual.rectangular.RectangularBorderLocation.getClosestLocationOnBounds; +import static org.fortiss.tooling.common.ui.javafx.lwfxef.visual.rectangular.RectangularContentVisualBase.getRectangularShapeDragGesture; import org.fortiss.tooling.common.ui.javafx.lwfxef.DiagramCoordinate; import org.fortiss.tooling.common.ui.javafx.lwfxef.DiagramLayers; @@ -21,7 +22,6 @@ import org.fortiss.tooling.common.ui.javafx.lwfxef.visual.IContentAnchorageVisua import org.fortiss.tooling.common.ui.javafx.lwfxef.visual.base.ContentVisualBase; import javafx.collections.ObservableList; -import javafx.geometry.Bounds; import javafx.geometry.Dimension2D; import javafx.geometry.Rectangle2D; import javafx.geometry.Side; @@ -35,6 +35,11 @@ import javafx.scene.shape.PathElement; /** Base class for {@link ContentVisualBase content visuals} depicted by a rhomboid. */ public abstract class RhomboidContentVisualBase extends ContentVisualBase { + /** The default horizontal offset multiplier. */ + private static final double DEFAULT_OFFSET_MULTIPLIER = 3.0; + /** The default corner arc. */ + private static final Dimension2D DEFAULT_CORNER_ARC = new Dimension2D(15, 15); + /** Constructor. */ public RhomboidContentVisualBase(IContentMVCBundle mvcb) { super(mvcb, new Path(), new Path()); @@ -86,8 +91,7 @@ public abstract class RhomboidContentVisualBase extends ContentVisualBase { /** Returns the offset of the upper and lower rhomboid line (0 = rectangle). */ public double getOffset() { - // TODO (SB): Magic constant - return 3.0 * getViewer().getFeatures().getHorizontalSpacing(); + return DEFAULT_OFFSET_MULTIPLIER * getViewer().getFeatures().getHorizontalSpacing(); } /** {@inheritDoc} */ @@ -124,39 +128,15 @@ public abstract class RhomboidContentVisualBase extends ContentVisualBase { /** Returns the dimensions of the corner arcs. */ protected Dimension2D getCornerArcDimensions() { - // TODO (SB): Magic constant - return new Dimension2D(15, 15); + return DEFAULT_CORNER_ARC; } /** {@inheritDoc} */ @Override protected EDragGesture dragGestureHitTest(Node node, DiagramCoordinate diagramLocation) { if(node == getHitAreaShape()) { - double x = diagramLocation.getLocalX(node); - double y = diagramLocation.getLocalY(node); - double l = getHitAreaStartLinkSize(); - double r = getHitAreaResizeSize(); - Bounds bounds = node.getBoundsInLocal(); - // check for move area - double inset = l + r; - Rectangle2D moveArea = new Rectangle2D(inset, inset, bounds.getWidth() - 2 * inset, - bounds.getHeight() - 2 * inset); - if(moveArea.contains(x, y)) { - return EDragGesture.MOVE; - } - if(x < l || y < l || x > bounds.getWidth() - l || y > bounds.getHeight() - l) { - return EDragGesture.NEW_LINK; - } - if(x > bounds.getWidth() - inset && y >= l && y <= bounds.getHeight() - inset) { - return EDragGesture.RESIZE_H; - } - if(y > bounds.getHeight() - inset && x >= l && x <= bounds.getWidth() - inset) { - return EDragGesture.RESIZE_V; - } - if(x > bounds.getWidth() - inset && y > bounds.getHeight() - inset) { - return EDragGesture.RESIZE_VH; - } - return EDragGesture.NONE; + return getRectangularShapeDragGesture(node, diagramLocation, getHitAreaStartLinkSize(), + getHitAreaResizeSize()); } if(node == getVisualShape() || node == text) { return EDragGesture.MOVE; diff --git a/org.fortiss.tooling.kernel.ui/plugin.xml b/org.fortiss.tooling.kernel.ui/plugin.xml index f84dd2cdad77ebdb72f81b1b3276d21dfba748ce..a6e2c25aa400760e0ecb8487b4e6b735e7a95f52 100644 --- a/org.fortiss.tooling.kernel.ui/plugin.xml +++ b/org.fortiss.tooling.kernel.ui/plugin.xml @@ -46,6 +46,13 @@ name="Model Elements" restorable="true"> </view> + <view + class="org.fortiss.tooling.kernel.ui.internal.views.ModelElementsViewFX" + icon="icons/library.png" + id="org.fortiss.tooling.kernel.model.element.view.fx" + name="Model Elements (FX)" + restorable="true"> + </view> <view allowMultiple="false" class="org.fortiss.tooling.kernel.ui.internal.introspection.KISSViewPart" diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/.ratings b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/.ratings index b57e572ddef97543ad02e1f91fca7eee0f6531c2..4dfe4762a07390bd5a303f6b7d8ba7446b51e4fa 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/.ratings +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/.ratings @@ -4,7 +4,7 @@ EObjectActionBase.java 4ef9f8be59e64d4838acc9e268d418ba5d94fa1a GREEN EReferenceListPropertySectionBase.java 7390dd7bfdc979e8ff0c5c30c67ab7b6c9d70c92 GREEN EReferencePropertySectionBase.java 0548da6778516003257f59d0b4c2b60d458be3b6 GREEN EditorBase.java 9c09fff92945256bb8680992ae7bb2c78f47b150 GREEN -FXEditorBase.java 545085c3270f09d69b609f328792e904ebda23ff GREEN +FXEditorBase.java 40caf638c7b4c02da5aece0d9d58883bce630e76 GREEN IListPropertySection.java 8bb00fe7959583e794ff9437b7a77404c9a9e70f GREEN LWFXEFEditorBase.java f6b160b700a0287021402b5702beb2bfdce3dc2e GREEN ModelEditorBindingBase.java b9b1a1c5a48a6e677d1f57ad55a6126d9703c4b5 GREEN diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/FXEditorBase.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/FXEditorBase.java index 545085c3270f09d69b609f328792e904ebda23ff..40caf638c7b4c02da5aece0d9d58883bce630e76 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/FXEditorBase.java +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/extension/base/FXEditorBase.java @@ -47,7 +47,6 @@ public abstract class FXEditorBase<T extends EObject> extends EditorBase<T> FXCanvas canvas = new FXCanvas(parent, SWT.NONE); Scene scene = new Scene(createSceneRoot()); canvas.setScene(scene); - getSite().setSelectionProvider(this); } diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/views/.ratings b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/views/.ratings index 75283430c8346ab6dfc5341b8e549540588a4d82..9384c7140bcbcaac075eeb60c1e3dd74a70b8dda 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/views/.ratings +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/views/.ratings @@ -5,6 +5,7 @@ LibraryViewDragSourceAdapter.java 56ef61b214ef5d6cb5b751791a92158bda0391ec GREEN LinkWithEditorPartListener.java c5ab74424378e7b158a805c4dd14fc03c8abeded GREEN MarkerViewContentProvider.java 4cb1192baebe21bca951c439c163d0c171512515 GREEN MarkerViewPart.java cbb650271b6877af205421b7cb11f930440a7ef9 GREEN +ModelElementsViewFX.java 5e1b3217eaa69c6d54c4300cdd1c744e36b3495b GREEN NavigatorNewMenu.java a35e391960d1dacbe7f77982e53e1891e9382d5a GREEN NavigatorTreeContentComparator.java d9f1354cfdff78b104b28887d2397e5ca0e9755b GREEN NavigatorTreeContentProvider.java 1fbe97bebf3805cc1af190cecd784fc1cfd12306 GREEN diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/views/ModelElementsViewFX.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/views/ModelElementsViewFX.java new file mode 100644 index 0000000000000000000000000000000000000000..5e1b3217eaa69c6d54c4300cdd1c744e36b3495b --- /dev/null +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/internal/views/ModelElementsViewFX.java @@ -0,0 +1,274 @@ +/*-------------------------------------------------------------------------+ +| Copyright 2020 fortiss GmbH | +| | +| Licensed under the Apache License, Version 2.0 (the "License"); | +| you may not use this file except in compliance with the License. | +| You may obtain a copy of the License at | +| | +| http://www.apache.org/licenses/LICENSE-2.0 | +| | +| Unless required by applicable law or agreed to in writing, software | +| distributed under the License is distributed on an "AS IS" BASIS, | +| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | +| See the License for the specific language governing permissions and | +| limitations under the License. | ++--------------------------------------------------------------------------*/ +package org.fortiss.tooling.kernel.ui.internal.views; + +import static java.util.Arrays.asList; +import static java.util.Collections.emptyList; +import static org.fortiss.tooling.kernel.service.IPrototypeService.PROTOTYPE_DATA_FORMAT; +import static org.fortiss.tooling.kernel.utils.EcoreUtils.filterOutInstanceOf; +import static org.fortiss.tooling.kernel.utils.KernelModelElementUtils.getParentElement; + +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.function.Predicate; + +import org.conqat.ide.commons.ui.ui.EmptyPartListener; +import org.conqat.lib.commons.collections.IdentityHashSet; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.fx.ui.workbench3.FXViewPart; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbenchPart; +import org.fortiss.tooling.common.ui.javafx.control.treetableview.DynamicTreeContentProviderBase; +import org.fortiss.tooling.common.ui.javafx.control.treetableview.DynamicTreeUIProviderBase; +import org.fortiss.tooling.common.ui.javafx.control.treetableview.DynamicTreeViewer; +import org.fortiss.tooling.kernel.extension.data.LibraryPrototype; +import org.fortiss.tooling.kernel.extension.data.Prototype; +import org.fortiss.tooling.kernel.extension.data.PrototypeCategory; +import org.fortiss.tooling.kernel.model.ILibraryElement; +import org.fortiss.tooling.kernel.service.IPrototypeService; +import org.fortiss.tooling.kernel.ui.extension.base.EditorBase; +import org.fortiss.tooling.kernel.ui.internal.editor.ExtendableMultiPageEditor; +import org.fortiss.tooling.kernel.ui.listener.ExtendableMultiPageEditorPageChangeListener; +import org.fortiss.tooling.kernel.ui.service.IModelElementHandlerService; + +import javafx.scene.Node; +import javafx.scene.Scene; +import javafx.scene.control.TextField; +import javafx.scene.input.ClipboardContent; +import javafx.scene.layout.BorderPane; + +/** + * {@link FXViewPart} for showing composable model elements with DND editing support. + * + * @author hoelzl + */ +public final class ModelElementsViewFX extends FXViewPart { + /** A dummy object serving as hidden root element of the tree view. */ + private static final Object DUMMY_ROOT = new Object(); + /** The tree-table viewer. */ + private DynamicTreeViewer<Object> treeViewer; + /** The filter text field if filtering is enabled in content provider. */ + private TextField filterWidget; + /** Current active {@link ExtendableMultiPageEditor}. */ + private ExtendableMultiPageEditor activeBindingEditor = null; + /** Stores the editor activation listener. */ + private EditorActivationListener editorActivationListener = new EditorActivationListener(); + /** The container object used. */ + private EObject containerObject = null; + /** The prototypes supported by the current editor. */ + private Set<Prototype> supportedBaseClasses = new IdentityHashSet<Prototype>(); + /** Listener for reacting to changes of the embedded editor. */ + private final ExtendableMultiPageEditorPageChangeListener bindingEditorPageChangeListener = + new ExtendableMultiPageEditorPageChangeListener() { + @Override + public void pageChanged() { + updateEditorFilters(activeBindingEditor.getActiveModelEditor()); + } + }; + + /** {@inheritDoc} */ + @Override + protected Scene createFxScene() { + getSite().getWorkbenchWindow().getPartService().addPartListener(editorActivationListener); + + BorderPane pane = new BorderPane(); + ContentProvider contentProvider = new ContentProvider(); + UIProvider uiProvider = new UIProvider(); + + filterWidget = new TextField(); + filterWidget.textProperty().addListener((obs, oVal, nVal) -> { + contentProvider.setFilterExpression(nVal); + treeViewer.update(); + }); + + treeViewer = new DynamicTreeViewer<>(DUMMY_ROOT, false, 2, contentProvider, uiProvider); + + pane.setTop(filterWidget); + pane.setCenter(treeViewer.getControl()); + + return new Scene(pane); + } + + /** {@inheritDoc} */ + @Override + protected void setFxFocus() { + filterWidget.requestFocus(); + } + + /** Updates the filters according to the given editor. */ + @SuppressWarnings("unchecked") + private void updateEditorFilters(IEditorPart editor) { + supportedBaseClasses.clear(); + if(editor instanceof EditorBase && + ((EditorBase<? extends EObject>)editor).enableLibraryView()) { + EditorBase<? extends EObject> editorBase = (EditorBase<? extends EObject>)editor; + containerObject = editorBase.getEditedObject(); + + for(Class<? extends EObject> clazz : editorBase.getVisibleEObjectTypes()) { + List<Prototype> composablePrototypes = + IPrototypeService.getInstance().getComposablePrototypes(clazz); + if(getParentElement(containerObject, ILibraryElement.class, true) == null) { + supportedBaseClasses.addAll(composablePrototypes); + } else { + supportedBaseClasses.addAll( + filterOutInstanceOf(LibraryPrototype.class, composablePrototypes)); + } + } + } else { + containerObject = null; + } + + treeViewer.update(); + treeViewer.expandAllItems(); + } + + /** Switches to the given workbench editor part. */ + private void switchWorkbenchEditor(IEditorPart editor) { + if(activeBindingEditor != null) { + activeBindingEditor.removeBindingEditorListener(bindingEditorPageChangeListener); + activeBindingEditor = null; + } + + if(editor instanceof ExtendableMultiPageEditor) { + activeBindingEditor = (ExtendableMultiPageEditor)editor; + activeBindingEditor.addBindingEditorListener(bindingEditorPageChangeListener); + updateEditorFilters(activeBindingEditor.getActiveModelEditor()); + } else if(editor != null) { + updateEditorFilters(editor); + } + } + + /** {@link DynamicTreeContentProviderBase} for the library view. */ + private class ContentProvider extends DynamicTreeContentProviderBase<Object> { + /** {@inheritDoc} */ + @Override + protected Collection<? extends Object> getChildren(Object parent) { + if(parent instanceof PrototypeCategory) { + PrototypeCategory protoCat = (PrototypeCategory)parent; + return asList(protoCat.getChildren()); + } + if(parent == DUMMY_ROOT) { + return IPrototypeService.getInstance().getAllTopLevelPrototypesCategories(); + } + return emptyList(); + } + + /** {@inheritDoc} */ + @Override + protected boolean filter(Object element, String filterValue) { + if(containerObject == null || supportedBaseClasses.isEmpty()) { + return false; + } + if(element instanceof PrototypeCategory) { + PrototypeCategory protoCat = (PrototypeCategory)element; + for(Object child : protoCat.getChildren()) { + if(filter(child, filterValue)) { + return true; + } + } + return false; + } + if(supportedBaseClasses.contains(element)) { + if(filterValue == null || "".equals(filterValue)) { + return true; + } + if(element instanceof Prototype) { + Prototype proto = (Prototype)element; + return proto.getName().contains(filterValue); + } + } + return false; + } + + /** {@inheritDoc} */ + @Override + protected Predicate<Object> getFilterPredicate(String filterValue) { + // this override is needed, because super implementation does not + // call filter(Object, String) when filter value is null. + if(filterValue == null || "".equals(filterValue)) { + return (o) -> { + return filter(o, null); + }; + } + return super.getFilterPredicate(filterValue); + } + } + + /** {@link DynamicTreeUIProviderBase} for the library view. */ + private class UIProvider extends DynamicTreeUIProviderBase<Object> { + /** {@inheritDoc} */ + @Override + public String getLabel(Object element) { + if(element instanceof Prototype) { + Prototype proto = (Prototype)element; + return proto.getName(); + } + if(element instanceof PrototypeCategory) { + PrototypeCategory protoCat = (PrototypeCategory)element; + return protoCat.getName(); + } + return element == null ? "" : element.toString(); + } + + /** {@inheritDoc} */ + @Override + public Node getIconNode(Object element) { + if(element instanceof Prototype) { + Prototype proto = (Prototype)element; + EObject eoPrototype = proto.getPrototype(); + return IModelElementHandlerService.getInstance().getFXIcon(eoPrototype); + } + if(element instanceof PrototypeCategory) { + PrototypeCategory protoCat = (PrototypeCategory)element; + if(protoCat.getChildren().length > 0) { + return getIconNode(protoCat.getChildren()[0]); + } + } + return null; + } + + /** {@inheritDoc} */ + @Override + public ClipboardContent getDragClipboardContent(Object element) { + if(element instanceof Prototype) { + Prototype proto = (Prototype)element; + String uid = IPrototypeService.getInstance().getUniquePrototypeID(proto); + if(uid != null) { + ClipboardContent cbContent = new ClipboardContent(); + cbContent.put(PROTOTYPE_DATA_FORMAT, uid); + return cbContent; + } + } + return null; + } + } + + /** If an editor in a different Project is opened the Model is reinitialized */ + private class EditorActivationListener extends EmptyPartListener { + /** Change the tree viewer content whenever workbench part changes. */ + @Override + public void partActivated(IWorkbenchPart workbenchPart) { + if(!(workbenchPart instanceof IEditorPart)) { + return; + } + + IEditorPart part = (IEditorPart)workbenchPart; + treeViewer.update(); + switchWorkbenchEditor(part); + } + } +} diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/.ratings b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/.ratings index 86599ae4e07d82e60443af868fe84e8d057ae40e..1ded5ea76b623771ecae670bf1ee96d08ee6e421 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/.ratings +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/.ratings @@ -4,6 +4,6 @@ IContextMenuService.java cfb6b8237b6cd2b0e461991a9ceb95969f330265 GREEN IEditPartFactoryService.java c448bff63fb81f57037c9f1dc5319859c12d0c4d GREEN IMarkerService.java d433e838e387dd2fe61b8dea7395ebb7203ae39b GREEN IModelEditorBindingService.java ce2ae1957e2232bb0fac1d1d262103f9adfc5266 GREEN -IModelElementHandlerService.java 1ff2bda9054f6bbd4017fc0ddc118b7702196815 GREEN +IModelElementHandlerService.java 748ffd22d6836a5599f8785f023469eb58c80ece GREEN INavigatorService.java 8d2ffeb6f075d3abea904b84d8a40090d97837fd GREEN ITutorialUIService.java 72707c60c3d23d8ffc5c579cb9b022bb614eb094 GREEN diff --git a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/IModelElementHandlerService.java b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/IModelElementHandlerService.java index 1ff2bda9054f6bbd4017fc0ddc118b7702196815..748ffd22d6836a5599f8785f023469eb58c80ece 100644 --- a/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/IModelElementHandlerService.java +++ b/org.fortiss.tooling.kernel.ui/src/org/fortiss/tooling/kernel/ui/service/IModelElementHandlerService.java @@ -31,11 +31,14 @@ import javafx.scene.Node; * @author hoelzl */ public interface IModelElementHandlerService { - /** The view ID of the model element library view. */ public static final String MODEL_ELEMENT_LIBRARY_VIEW = "org.fortiss.tooling.kernel.model.element.library"; + /** The view ID of the model element library view. */ + public static final String MODEL_ELEMENT_LIBRARY_VIEW_FX = + "org.fortiss.tooling.kernel.model.element.view.fx"; + /** Returns the service instance. */ public static IModelElementHandlerService getInstance() { return ModelElementHandlerService.getInstance(); diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/.ratings b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/.ratings index b2f23c1f28fd6be6f4cd785dfbd17d06d59c5604..5e2380be4958d336c5e17b8c89eb59d2f5f38068 100644 --- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/.ratings +++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/.ratings @@ -1,5 +1,4 @@ IConnectionCompositor.java 82188750593a08df75a5f21fd91d4b41f72593fd GREEN -IConstraint.java e5e95efa8b06b30d6feffd9a2033e5caa3e710e9 GREEN IConstraintChecker.java a6d76e332ece919adb990397dd5ef6aaa542ea7d GREEN IEclipseResourcePostLoadProvider.java e842bb7485ef27917092ffc60af8a57e475d01d6 GREEN IEclipseResourceStorageLocationProvider.java 0ab7f304d52a9d86f01f66e308e9a7ca420497ba GREEN @@ -7,7 +6,7 @@ IElementCompositor.java 5b0ab1732f71b3f8467e0276c844f0dd549e191f GREEN ILibraryElementHandler.java 00ef5b25c63b8570006e6f6748aed0da1f33a5f1 GREEN ILogMessageHandler.java 9ab53e836a095ef00fd84ecc0375167edf593b46 GREEN IMigrationProvider.java 241bfd8594dfb86ce0f89dc95b43662f52d9e450 GREEN -IPrototypeProvider.java d5e3dbae19b5654caf28b81da6b1609d3c12be12 GREEN +IPrototypeProvider.java 5a135f31c5b65a9ebd3432f6d65fd790992b724b GREEN IStorageProvider.java d9b14cdd254d0c956dc5715c1c4d4d955a705dd5 GREEN ITransformationProvider.java a4ee2ea08720bb2fce29806062eb01499bb5071e GREEN ITutorialProvider.java 0f649c7856fc0e13c5dd71e116ee8bf4ba372216 GREEN diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/IPrototypeProvider.java b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/IPrototypeProvider.java index d5e3dbae19b5654caf28b81da6b1609d3c12be12..5a135f31c5b65a9ebd3432f6d65fd790992b724b 100644 --- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/IPrototypeProvider.java +++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/IPrototypeProvider.java @@ -33,10 +33,21 @@ import org.fortiss.tooling.kernel.service.IPrototypeService; * @author hoelzl */ public interface IPrototypeProvider { - /** Returns the prototypes provided by this provider. */ List<Prototype> getPrototypes(); /** Returns the categories of prototypes. */ List<PrototypeCategory> getCategories(); + + /** + * Returns a unique ID for the given {@link Prototype} or {@code null} if the prototype does not + * stem from this provider. + */ + String getUniqueID(Prototype prototype); + + /** + * Returns the {@link Prototype} for the given unique ID or {@code null} if the unique ID does + * not correspond to any prototype of this provider. + */ + Prototype getPrototypeByID(String id); } diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/base/.ratings b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/base/.ratings index 05ded098fabef31e2ecff7e4dce51ee5a048c083..6b447aea1fbd80532b5e65df1d470cce27e1128e 100644 --- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/base/.ratings +++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/base/.ratings @@ -1,10 +1,8 @@ -ConstraintBases.java 93b4743cc1f5e2677635e644663ba934ef7f7f4e GREEN ConstraintCheckerBase.java 92de33f1a3071dc6d66a55d8c10f5d5cc967a4fc GREEN ConstraintViolationBase.java ec66973ab2183623f0cd4a85c59c886dddad6cf6 GREEN DialogMessage.java 8420640e999e4fb15fa644333e5d71e1d16c2559 GREEN ElementCompositorBase.java 7a445e5adde11878fe0515baca8b915287149b28 GREEN MultiViolationConstraintCheckerBase.java 30886a94c99cf8948f64401b1db821abe06e1e6c GREEN -PrototypeProviderBase.java ebcd1794c3798b9899a620b01fd5aa0402129423 GREEN -RemoveDeprecatedArtifactsMigrationProviderBase.java 4a1b676223b7ec53259a26d1a671b11ff2f911e2 GREEN +PrototypeProviderBase.java b433cffcaf020987c84df8c127dac871e0fd8fb9 GREEN TransformationContextChainBase.java 1ef37880ab275778c563928e80ba378fec964cb6 GREEN TransformationProviderBase.java 9e91100cc1f2c8fbd8d41af55aedfea34e02ff71 GREEN diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/base/PrototypeProviderBase.java b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/base/PrototypeProviderBase.java index ebcd1794c3798b9899a620b01fd5aa0402129423..b433cffcaf020987c84df8c127dac871e0fd8fb9 100644 --- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/base/PrototypeProviderBase.java +++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/extension/base/PrototypeProviderBase.java @@ -15,12 +15,13 @@ +--------------------------------------------------------------------------*/ package org.fortiss.tooling.kernel.extension.base; +import static org.conqat.lib.commons.collections.CollectionUtils.asUnmodifiable; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.conqat.lib.commons.collections.CollectionUtils; import org.eclipse.emf.ecore.EObject; import org.fortiss.tooling.kernel.extension.IPrototypeProvider; import org.fortiss.tooling.kernel.extension.data.Prototype; @@ -76,7 +77,7 @@ public abstract class PrototypeProviderBase implements IPrototypeProvider { /** {@inheritDoc} */ @Override public final List<Prototype> getPrototypes() { - return CollectionUtils.asUnmodifiable(prototypes); + return asUnmodifiable(prototypes); } /** Registers the element with the given category. */ @@ -111,4 +112,33 @@ public abstract class PrototypeProviderBase implements IPrototypeProvider { result.addAll(categories.values()); return result; } + + /** {@inheritDoc} */ + @Override + public final String getUniqueID(Prototype prototype) { + if(!prototypes.contains(prototype)) { + return null; + } + return this.getClass().getName() + '/' + prototype.getName(); + } + + /** {@inheritDoc} */ + @Override + public final Prototype getPrototypeByID(String id) { + String cname = this.getClass().getName(); + if(!id.startsWith(cname)) { + return null; + } + id = id.substring(cname.length()); + if(!id.startsWith("/")) { + return null; + } + id = id.substring(1); + for(Prototype p : prototypes) { + if(p.getName().equals(id)) { + return p; + } + } + return null; + } } diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/.ratings b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/.ratings index 95a442ad4aea705c31e35a4f2b5c4016bc201a16..25ccdaebcf83b05dab4a8bf0790072cfde60e268 100644 --- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/.ratings +++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/.ratings @@ -8,7 +8,7 @@ LibraryService.java d22671ba820466062852c15873698adf28960d94 GREEN LoggingService.java da784259f7b456b54bf75c41ec268f64919ce78d GREEN MigrationService.java 2f800eac9793aa736089a802bbfc2c4c1c09770d GREEN PersistencyService.java 103eef642c038ef63fa49b743d803aaa3fea2724 GREEN -PrototypeService.java 18c3db05ab11f189a9711bf241c3c7f35c954a9e GREEN +PrototypeService.java cf8e6fa96ba9c2f65b24400054ed68e93238a975 GREEN ToolingKernelInternal.java f6e7114825748683c7f1d040b41ab854a6c4d79b GREEN TransformationService.java 3cdb86fe920158f93cd9466c6ef9697b2dd8ca7f GREEN TutorialService.java 675d3f365ce062869f86baa3779d50687674bda0 GREEN diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/PrototypeService.java b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/PrototypeService.java index 18c3db05ab11f189a9711bf241c3c7f35c954a9e..cf8e6fa96ba9c2f65b24400054ed68e93238a975 100644 --- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/PrototypeService.java +++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/internal/PrototypeService.java @@ -162,6 +162,30 @@ public class PrototypeService implements IPrototypeService, IIntrospectiveKernel return result; } + /** {@inheritDoc} */ + @Override + public String getUniquePrototypeID(Prototype prototype) { + for(IPrototypeProvider prov : prototypeProviderList) { + String uid = prov.getUniqueID(prototype); + if(uid != null) { + return uid; + } + } + return null; + } + + /** {@inheritDoc} */ + @Override + public Prototype getPrototypeByUniqueID(String id) { + for(IPrototypeProvider prov : prototypeProviderList) { + Prototype proto = prov.getPrototypeByID(id); + if(proto != null) { + return proto; + } + } + return null; + } + /** {@inheritDoc} */ @Override public List<Prototype> getComposablePrototypes(Class<? extends EObject> modelElementType) { diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/service/.ratings b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/service/.ratings index 6c4b249d4c461573e0cc2f252d59d8ba4b6995cb..c0b2fd39efac3856916011308f3011fed579bf1e 100644 --- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/service/.ratings +++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/service/.ratings @@ -1,7 +1,6 @@ ICommandStackService.java 678dcd1a6ab435ed0870fa2a9ec48ce47f25a187 GREEN IConnectionCompositorService.java 0cdf4568b2cd3e95ea195df90a84699eff36442b GREEN IConstraintCheckerService.java 291e53297aaea213e07e78f63350938ee2c7b155 GREEN -IConstraintService.java d55c3e25b8cef7e2f7c555adec7ff31e28449370 GREEN IEclipseResourceStorageService.java b1155ca15cd9474d4d533d6cb2725e8a22040ec9 GREEN IElementCompositorService.java acd462ec15f3bcc247b544b46ceebee971fe1408 GREEN IKernelIntrospectionSystemService.java 7005c3acb4c6f978729d93279c595765e94e38eb GREEN @@ -9,6 +8,6 @@ ILibraryService.java e1e2ec72b1db892478ed20c7fbb7dcf94472a1cd GREEN ILoggingService.java 1ee9723af5a79299249e8db345e8419f814ff6d1 GREEN IMigrationService.java 7cfa6268b97f0c38c838905791e065655c6d6a04 GREEN IPersistencyService.java 2b2eeb329e3040e75f4352d9c374855583e27538 GREEN -IPrototypeService.java 47f5ab07c17d5da704860378a49493fa83b3e20b GREEN +IPrototypeService.java d2b66742bea8bd6d394157985def6f8ea39c8d20 GREEN ITransformationService.java 71f175e94d7257713cb14c8148de5a309b03788a GREEN ITutorialService.java 22a490516e38536203b1edd32711b615b77a4728 GREEN diff --git a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/service/IPrototypeService.java b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/service/IPrototypeService.java index 47f5ab07c17d5da704860378a49493fa83b3e20b..d2b66742bea8bd6d394157985def6f8ea39c8d20 100644 --- a/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/service/IPrototypeService.java +++ b/org.fortiss.tooling.kernel/src/org/fortiss/tooling/kernel/service/IPrototypeService.java @@ -24,6 +24,8 @@ import org.fortiss.tooling.kernel.extension.data.Prototype; import org.fortiss.tooling.kernel.extension.data.PrototypeCategory; import org.fortiss.tooling.kernel.internal.PrototypeService; +import javafx.scene.input.DataFormat; + /** * The prototype service provides registration and access to model element * prototypes. It distinguishes between two types of prototypes. Primary @@ -37,6 +39,10 @@ import org.fortiss.tooling.kernel.internal.PrototypeService; * @author hoelzl */ public interface IPrototypeService { + /** The DataFormat used to transfer prototypes via drag-and-drop. */ + public static final DataFormat PROTOTYPE_DATA_FORMAT = + new DataFormat(IPrototypeService.class.getName()); + /** Returns the service instance. */ public static IPrototypeService getInstance() { return PrototypeService.getInstance(); @@ -51,6 +57,15 @@ public interface IPrototypeService { /** Returns the list of primary prototypes registered any provider. */ UnmodifiableList<Prototype> getPrimaryPrototypes(); + /** Returns a unique ID for the given {@link Prototype}. */ + String getUniquePrototypeID(Prototype prototype); + + /** + * Returns the {@link Prototype} for the given unique ID or {@code null} if the unique ID does + * not correspond to any prototype of any provider. + */ + Prototype getPrototypeByUniqueID(String id); + /** * Returns the list of all prototypes composable with the given model * element class.