/* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * 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.kie.workbench.common.stunner.client.lienzo.components.drag; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.ait.lienzo.client.core.shape.MultiPath; import com.ait.lienzo.client.core.shape.wires.WiresConnector; import com.ait.lienzo.client.core.shape.wires.WiresManager; import com.ait.lienzo.client.core.shape.wires.WiresShape; import org.kie.workbench.common.stunner.client.lienzo.LienzoLayer; import org.kie.workbench.common.stunner.core.client.canvas.AbstractCanvas; import org.kie.workbench.common.stunner.core.client.canvas.AbstractCanvasHandler; import org.kie.workbench.common.stunner.core.client.canvas.Point2D; import org.kie.workbench.common.stunner.core.client.components.drag.ConnectorDragProxy; import org.kie.workbench.common.stunner.core.client.components.drag.DragProxy; import org.kie.workbench.common.stunner.core.client.components.drag.DragProxyCallback; import org.kie.workbench.common.stunner.core.client.components.drag.ShapeViewDragProxy; import org.kie.workbench.common.stunner.core.client.shape.EdgeShape; import org.kie.workbench.common.stunner.core.client.shape.MutationContext; import org.kie.workbench.common.stunner.core.client.shape.Shape; import org.kie.workbench.common.stunner.core.client.shape.factory.ShapeFactory; import org.kie.workbench.common.stunner.core.client.shape.view.ShapeView; import org.kie.workbench.common.stunner.core.graph.Edge; import org.kie.workbench.common.stunner.core.graph.Node; import org.kie.workbench.common.stunner.core.graph.content.view.View; import org.kie.workbench.common.stunner.core.graph.processing.index.bounds.GraphBoundsIndexer; @Dependent public class ConnectorDragProxyImpl implements ConnectorDragProxy<AbstractCanvasHandler> { ShapeViewDragProxy<AbstractCanvas> shapeViewDragProxyFactory; GraphBoundsIndexer graphBoundsIndexer; private AbstractCanvasHandler canvasHandler; private WiresConnector wiresConnector; @Inject public ConnectorDragProxyImpl(final ShapeViewDragProxy<AbstractCanvas> shapeViewDragProxyFactory, final GraphBoundsIndexer graphBoundsIndexer) { this.shapeViewDragProxyFactory = shapeViewDragProxyFactory; this.graphBoundsIndexer = graphBoundsIndexer; } @Override public DragProxy<AbstractCanvasHandler, Item, DragProxyCallback> proxyFor(final AbstractCanvasHandler context) { this.canvasHandler = context; this.shapeViewDragProxyFactory.proxyFor(context.getAbstractCanvas()); this.graphBoundsIndexer.setRootUUID(context.getDiagram().getMetadata().getCanvasRootUUID()); return this; } @Override @SuppressWarnings("unchecked") public DragProxy<AbstractCanvasHandler, Item, DragProxyCallback> show(final Item item, final int x, final int y, final DragProxyCallback callback) { final Edge<View<?>, Node> edge = item.getEdge(); final Node<View<?>, Edge> sourceNode = item.getSourceNode(); final ShapeFactory<Object, AbstractCanvasHandler, ?> factory = (ShapeFactory<Object, AbstractCanvasHandler, ?>) item.getShapeFactory(); final WiresManager wiresManager = getWiresManager(); final Shape<?> sourceNodeShape = getCanvas().getShape(sourceNode.getUUID()); final Shape<?> shape = factory.build(edge.getContent().getDefinition(), canvasHandler); final EdgeShape connector = (EdgeShape) shape; this.wiresConnector = (WiresConnector) shape.getShapeView(); wiresManager.register(wiresConnector); final MultiPath dummyPath = new MultiPath().rect(0, 0, 1, 1).setFillAlpha(0).setStrokeAlpha(0); final DummyShapeView dummyShapeView = new DummyShapeView(dummyPath); graphBoundsIndexer.build(canvasHandler.getDiagram().getGraph()); shapeViewDragProxyFactory.show(dummyShapeView, x, y, new DragProxyCallback() { @Override public void onStart(final int x, final int y) { callback.onStart(x, y); drawConnector(); } @Override public void onMove(final int x, final int y) { callback.onMove(x, y); drawConnector(); } @Override public void onComplete(final int x, final int y) { callback.onComplete(x, y); deregisterTransientConnector(); getCanvas().draw(); } private void drawConnector() { ShapeView<?> targetShapeView = null; // TODO: Apply target connection to mouse pointer, in adittion check if allowed connection to node at current pos is ok -> automatically connect to it // final Node targetNode = graphBoundsIndexer.getAt( x, y ); final Node targetNode = null; if (null != targetNode) { final Shape<?> targetNodeShape = getCanvas().getShape(targetNode.getUUID()); if (null != targetNodeShape) { targetShapeView = targetNodeShape.getShapeView(); } } else { targetShapeView = dummyShapeView; } connector.applyConnections(edge, sourceNodeShape.getShapeView(), targetShapeView, MutationContext.STATIC); connector.applyProperties(edge, MutationContext.STATIC); getCanvas().draw(); } }); return this; } @Override public void clear() { if (null != this.shapeViewDragProxyFactory) { this.shapeViewDragProxyFactory.clear(); } deregisterTransientConnector(); } public void destroy() { clear(); this.graphBoundsIndexer.destroy(); this.graphBoundsIndexer = null; this.canvasHandler = null; this.shapeViewDragProxyFactory.destroy(); this.shapeViewDragProxyFactory = null; } private WiresManager getWiresManager() { final AbstractCanvas<?> canvas = canvasHandler.getAbstractCanvas(); final LienzoLayer layer = (LienzoLayer) canvas.getLayer(); return WiresManager.get(layer.getLienzoLayer()); } private void deregisterTransientConnector() { if (null != this.wiresConnector) { getWiresManager().deregister(wiresConnector); getCanvas().draw(); this.wiresConnector = null; } } private AbstractCanvas<?> getCanvas() { return canvasHandler.getAbstractCanvas(); } private class DummyShapeView extends WiresShape implements ShapeView<DummyShapeView> { public DummyShapeView(final MultiPath path) { super(path); } @Override public DummyShapeView setUUID(final String uuid) { return null; } @Override public String getUUID() { return null; } @Override public double getShapeX() { return 0; } @Override public double getShapeY() { return 0; } @Override public DummyShapeView setShapeX(final double x) { return null; } @Override public DummyShapeView setShapeY(final double y) { return null; } @Override public double getAlpha() { return 0; } @Override public DummyShapeView setAlpha(final double alpha) { return this; } @Override public Point2D getShapeAbsoluteLocation() { return new Point2D(0, 0); } @Override public String getFillColor() { return null; } @Override public DummyShapeView setFillColor(final String color) { return null; } @Override public double getFillAlpha() { return 0; } @Override public DummyShapeView setFillAlpha(final double alpha) { return null; } @Override public String getStrokeColor() { return null; } @Override public DummyShapeView setStrokeColor(final String color) { return null; } @Override public double getStrokeAlpha() { return 0; } @Override public DummyShapeView setStrokeAlpha(final double alpha) { return null; } @Override public double getStrokeWidth() { return 0; } @Override public DummyShapeView setStrokeWidth(final double width) { return null; } @Override public DummyShapeView moveToTop() { return null; } @Override public DummyShapeView moveToBottom() { return null; } @Override public DummyShapeView moveUp() { return null; } @Override public DummyShapeView moveDown() { return null; } @Override public void destroy() { } } }