From ba762b0dee4358c59a878ec94727c0379c77c727 Mon Sep 17 00:00:00 2001 From: Florian Hoelzl <hoelzl@fortiss.org> Date: Tue, 26 Nov 2019 13:49:24 +0100 Subject: [PATCH] Kernel: Added FX image load utility and elliptic content controller. Issue-Ref: 3873 Issue-Url: https://af3-developer.fortiss.org/issues/3815 Signed-off-by: Florian Hoelzl <hoelzl@fortiss.org> --- .../tooling/base/ui/editor/fx/.ratings | 1 + ...llipticResizableContentControllerBase.java | 146 ++++++++++++++++++ .../fortiss/tooling/base/ui/utils/.ratings | 2 +- .../base/ui/utils/LWFXEditorUtils.java | 34 ++++ 4 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/EObjectBasedEllipticResizableContentControllerBase.java diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/.ratings b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/.ratings index e65316624..2af896f26 100644 --- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/.ratings +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/.ratings @@ -1,5 +1,6 @@ ContextMenuUtil.java 3e04dbd52ee99a59735d39b4087c55b07fb91076 GREEN EObjectBasedDiagramControllerBase.java b25bbbaa6eef3878b9aea73ca67d66de9beebb18 GREEN +EObjectBasedEllipticResizableContentControllerBase.java 7d04a93fdce63e0542e78433cc3da7e112ed1b88 YELLOW EObjectBasedRectangularResizableContentControllerBase.java a263a6c123ee96015e0a5c37b6e3c13ebd0e8a75 GREEN HierarchicModelElementModelChangeProvider.java 05217577a99d78038763bbcd841a032bb84f0553 GREEN KernelServiceBasedModelChangeProviderBase.java 7c30347fb0c7cc4aacc79aeaf85167872afc1958 GREEN diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/EObjectBasedEllipticResizableContentControllerBase.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/EObjectBasedEllipticResizableContentControllerBase.java new file mode 100644 index 000000000..7d04a93fd --- /dev/null +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/editor/fx/EObjectBasedEllipticResizableContentControllerBase.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * Copyright (c) 2017, 2018 fortiss GmbH. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v2.0 which is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Florian Hoelzl (fortiss GmbH) - initial implementation + * + *******************************************************************************/ +package org.fortiss.tooling.base.ui.editor.fx; + +import static java.lang.Math.max; +import static org.fortiss.tooling.base.ui.editor.fx.ContextMenuUtil.createElementCompositionContext; +import static org.fortiss.tooling.base.ui.editor.fx.ContextMenuUtil.createPrototypeMenu; + +import java.util.List; + +import org.eclipse.emf.common.notify.Notification; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramCoordinate; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramViewerFeatures; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.change.Change; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.IClickController; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.base.ClickControllerBase; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.elliptic.EllipticResizableContentControllerBase; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.controller.rectangular.RectangularResizableContentControllerBase; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.model.IModelChangeProvider; +import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.mvc.IContentMVCBundle; +import org.fortiss.tooling.base.model.element.ElementPackage; +import org.fortiss.tooling.base.model.layout.ILayoutedModelElement; +import org.fortiss.tooling.kernel.extension.data.IElementCompositionContext; +import org.fortiss.tooling.kernel.service.IElementCompositorService; +import org.fortiss.tooling.kernel.ui.extension.IModelElementHandler; +import org.fortiss.tooling.kernel.ui.service.IModelEditorBindingService; +import org.fortiss.tooling.kernel.ui.service.IModelElementHandlerService; + +import javafx.scene.Node; +import javafx.scene.control.MenuItem; +import javafx.scene.input.MouseEvent; + +/** + * {@link RectangularResizableContentControllerBase} with a listener mechanism for the layout of the + * connected {@link EObject model element}. + * + * @author hoelzl + */ +public abstract class EObjectBasedEllipticResizableContentControllerBase + extends EllipticResizableContentControllerBase { + /** {@link IModelChangeProvider} for this controller */ + private final LayoutModelElementModelChangeProvider layoutModelChangeProvider; + /** The click controller handling double-click to open editor. */ + private final IClickController openEditorDoubleClickController = new ClickControllerBase() { + @Override + public Change singleClick(MouseEvent event, Node node, DiagramCoordinate diagramLocation) { + return EObjectBasedEllipticResizableContentControllerBase.super.getClickController(node, + diagramLocation).singleClick(event, node, diagramLocation); + } + + @Override + public Change secondaryClick(MouseEvent event, Node node, + DiagramCoordinate diagramLocation) { + return EObjectBasedEllipticResizableContentControllerBase.super.getClickController(node, + diagramLocation).secondaryClick(event, node, diagramLocation); + } + + @Override + public Change doubleClick(MouseEvent event, Node node, DiagramCoordinate diagramLocation) { + EObject eo = getLayoutedME(); + IModelElementHandler<EObject> handler = + IModelElementHandlerService.getInstance().getModelElementHandler(eo); + if(handler != null) { + eo = handler.handleOpenModelElementRequest(eo); + } + IModelEditorBindingService.getInstance().openInEditor(eo); + return null; // no changes to model + } + }; + + /** Constructor. */ + public EObjectBasedEllipticResizableContentControllerBase(IContentMVCBundle mvcb) { + super(mvcb); + if(!(mvcb.getModel() instanceof ILayoutedModelElement)) { + throw new IllegalArgumentException( + "Model element must be an instance of an ILayoutedModelElement."); + } + ILayoutedModelElement lme = (ILayoutedModelElement)mvcb.getModel(); + this.layoutModelChangeProvider = new LayoutModelElementModelChangeProvider(lme) { + /** {@inheritDoc} */ + @Override + protected boolean acceptNotification(Notification notification) { + if(notification.getNotifier() != getLayoutedME()) { + return false; + } + return isAnchorageFeature(notification.getFeature()); + } + }; + } + + /** Returns the {@link ILayoutedModelElement} model element. */ + protected ILayoutedModelElement getLayoutedME() { + // wild cast works: see constructor check with exception + return (ILayoutedModelElement)getModel(); + } + + /** {@inheritDoc} */ + @Override + public IModelChangeProvider getModelChangeProvider() { + return layoutModelChangeProvider; + } + + /** {@inheritDoc} */ + @Override + public List<MenuItem> contextMenuContributions(Node node, DiagramCoordinate diagramLocation) { + // outer-most grid areas of the diagram are inaccessible + DiagramViewerFeatures features = getViewer().getFeatures(); + double x = max(features.getHorizontalSpacing(), diagramLocation.getX()); + double y = max(features.getVerticalSpacing(), diagramLocation.getY()); + + // wild cast works: see constructor exception + EObject modelParent = (EObject)getModel(); + IElementCompositionContext edc = createElementCompositionContext(modelParent, x, y, false, + getViewer().getFeatures().getCurrentZoomFactor()); + return createPrototypeMenu(modelParent, edc); + } + + /** {@inheritDoc} */ + @Override + public void delete() { + IElementCompositorService.getInstance().decompose(getLayoutedME()); + } + + /** Checks whether the given feature corresponds to an anchorage model element. */ + protected boolean isAnchorageFeature(Object feature) { + return feature == ElementPackage.Literals.IHIERARCHIC_ELEMENT__CONNECTORS; + } + + /** {@inheritDoc} */ + @Override + public IClickController getClickController(Node node, DiagramCoordinate diagramLocation) { + return openEditorDoubleClickController; + } +} 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 27fbc6fb9..c0c902300 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 @@ -5,7 +5,7 @@ DragAndDropBaseUtils.java d375377f9124f6113b2a295e6b0e09ac8966e564 GREEN EllipseLayoutUIUtils.java 4dd9dbd96a45e8c455c019caa19e4a50f18336af GREEN FontUtils.java a167a05bdaa8da9853705cc5134f30f6d81bc9f2 GREEN GCStateManager.java 983973a92376b5c757c1253b32e33d0666ccdf7b GREEN -LWFXEditorUtils.java c628e79fa43c1be8a7b87ee90db6e7264904eafc GREEN +LWFXEditorUtils.java c6a08711872a74aa52078bba25a3a4adeddc348c YELLOW LayoutDataUIUtils.java c85886ac313a6efb122532218eb134047ffd6631 GREEN PropertiesViewUtils.java d345b4501c4092228edf1c98e0189317d53aaf22 GREEN RectangleLayoutUIUtils.java ef4b872bb5b4a51174e9a29d9ef05e7cb3bff3a1 GREEN diff --git a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/utils/LWFXEditorUtils.java b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/utils/LWFXEditorUtils.java index c628e79fa..c6a087118 100644 --- a/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/utils/LWFXEditorUtils.java +++ b/org.fortiss.tooling.base.ui/src/org/fortiss/tooling/base/ui/utils/LWFXEditorUtils.java @@ -19,12 +19,18 @@ import static java.lang.Math.atan2; import static java.lang.Math.cos; import static java.lang.Math.sin; +import java.io.InputStream; +import java.net.URL; +import java.util.HashMap; + import org.eclipse.systemfocus.kernel.common.ui.javafx.lwfxef.DiagramCoordinate; import org.fortiss.tooling.base.model.layout.EOrientation; import javafx.geometry.Point2D; import javafx.geometry.Rectangle2D; import javafx.geometry.Side; +import javafx.scene.image.Image; +import javafx.scene.paint.Color; /** * Utility methods for the JavaFX-based graphical LWFXEF editors. @@ -99,6 +105,34 @@ public final class LWFXEditorUtils { return new DiagramCoordinate(nx, ny); } + /** The image cache of loaded images. */ + private static final HashMap<String, Image> imageCache = new HashMap<>(); + + /** Returns the Java FX Image load from the local path. */ + public static Image getFXImage(String pluginId, String localPath) { + String uri = "platform:/plugin/" + pluginId + localPath; + Image cacheImage = imageCache.get(uri); + if(cacheImage == null) { + InputStream in = null; + try { + in = new URL(uri).openStream(); + } catch(Exception e) { + e.printStackTrace(); + } + if(in != null) { + cacheImage = new Image(in); + } + imageCache.put(uri, cacheImage); + } + return cacheImage; + } + + /** Converts the given SWT color to Java FX color. */ + public static Color convertColor(org.eclipse.swt.graphics.Color swtColor) { + return Color.rgb(swtColor.getRed(), swtColor.getGreen(), swtColor.getBlue(), + swtColor.getAlpha() / 255.0); + } + /** Constructor. */ private LWFXEditorUtils() { // prevent instantiation -- GitLab