/* * Copyright 2017 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; import javax.enterprise.context.Dependent; import com.ait.lienzo.client.core.shape.IPrimitive; import com.ait.lienzo.client.core.shape.Shape; import com.ait.lienzo.client.core.shape.Viewport; import com.ait.lienzo.client.core.shape.wires.WiresConnector; import com.ait.lienzo.client.core.shape.wires.WiresContainer; import com.ait.lienzo.client.core.types.Transform; import com.ait.lienzo.shared.core.types.DataURLType; import org.kie.workbench.common.stunner.client.lienzo.canvas.util.LienzoImageDataUtils; import org.kie.workbench.common.stunner.client.lienzo.canvas.wires.WiresUtils; import org.kie.workbench.common.stunner.client.lienzo.shape.view.ViewEventHandlerManager; import org.kie.workbench.common.stunner.core.client.canvas.AbstractLayer; import org.kie.workbench.common.stunner.core.client.canvas.Point2D; import org.kie.workbench.common.stunner.core.client.shape.view.ShapeView; import org.kie.workbench.common.stunner.core.client.shape.view.event.ViewEvent; import org.kie.workbench.common.stunner.core.client.shape.view.event.ViewEventType; import org.kie.workbench.common.stunner.core.client.shape.view.event.ViewHandler; import org.uberfire.mvp.Command; /** * An Stunner's Layer type implementation that wraps a Lienzo layer and provides * support for primitives, shapes and wires. */ @Dependent @Lienzo public class LienzoLayer extends AbstractLayer<LienzoLayer, ShapeView<?>, Shape<?>> { private static final ViewEventType[] SUPPORTED_EVENT_TYPES = new ViewEventType[]{ ViewEventType.MOUSE_CLICK, ViewEventType.MOUSE_DBL_CLICK, ViewEventType.MOUSE_MOVE }; protected ViewEventHandlerManager eventHandlerManager; protected com.ait.lienzo.client.core.shape.Layer layer; public LienzoLayer() { } @Override public LienzoLayer initialize(final Object view) { this.layer = (com.ait.lienzo.client.core.shape.Layer) view; this.eventHandlerManager = new ViewEventHandlerManager(layer, layer, SUPPORTED_EVENT_TYPES); return this; } @Override public LienzoLayer addShape(final ShapeView<?> shape) { if (WiresUtils.isWiresContainer(shape)) { layer.add(((WiresContainer) shape).getGroup()); } else if (WiresUtils.isWiresConnector(shape)) { layer.add(((WiresConnector) shape).getLine()); } else { layer.add((IPrimitive<?>) shape); } return this; } @Override public LienzoLayer removeShape(final ShapeView<?> shape) { if (WiresUtils.isWiresContainer(shape)) { layer.remove(((WiresContainer) shape).getGroup()); } else if (WiresUtils.isWiresConnector(shape)) { layer.remove(((WiresConnector) shape).getLine()); } else { layer.remove((IPrimitive<?>) shape); } return this; } @Override public LienzoLayer draw() { layer.batch(); return this; } @Override public void clear() { layer.clear(); } @Override public String toDataURL() { return layer.toDataURL(DataURLType.PNG); } @Override public String toDataURL(final int x, final int y, final int width, final int height) { return LienzoImageDataUtils.toImageData(getLienzoLayer(), x, y, width, height); } @Override public void onAfterDraw(final Command callback) { layer.setOnLayerAfterDraw(layer1 -> callback.execute()); } @Override public void destroy() { // Clear registered event handers. if (null != eventHandlerManager) { eventHandlerManager.destroy(); eventHandlerManager = null; } // Remove the layer stuff. if (null != layer) { layer.removeAll(); layer.removeFromParent(); layer = null; } } @Override public boolean supports(final ViewEventType type) { return eventHandlerManager.supports(type); } @Override public LienzoLayer addHandler(final ViewEventType type, final ViewHandler<? extends ViewEvent> eventHandler) { eventHandlerManager.addHandler(type, eventHandler); return this; } @Override public LienzoLayer removeHandler(final ViewHandler<? extends ViewEvent> eventHandler) { eventHandlerManager.removeHandler(eventHandler); return this; } @Override public LienzoLayer enableHandlers() { eventHandlerManager.enable(); return this; } @Override public LienzoLayer disableHandlers() { eventHandlerManager.disable(); return this; } @Override public Shape<?> getAttachableShape() { return null; } public com.ait.lienzo.client.core.shape.Layer getLienzoLayer() { return this.layer; } @Override protected Point2D getTranslate() { return new Point2D( layer.getAbsoluteTransform().getTranslateX(), layer.getAbsoluteTransform().getTranslateY() ); } @Override protected Point2D getScale() { return new Point2D( layer.getAbsoluteTransform().getScaleX(), layer.getAbsoluteTransform().getScaleY() ); } public void translate(final double tx, final double ty) { setTransform(t -> translate(t, tx, ty)); } public void scale(final double sx, final double sy) { setTransform(t -> scale(t, sx, sy)); } public void scale(final double delta) { setTransform(t -> scale(t, delta)); } private interface TransformCallback { void apply(Transform transform); } private void setTransform(final TransformCallback callback) { Transform transform = getViewPort().getTransform(); if (transform == null) { getViewPort().setTransform(transform = new Transform()); } callback.apply(transform); getViewPort().setTransform(transform); getViewPort().getScene().batch(); } private void scale(final Transform transform, final double sx, final double sy) { transform.scale(sx, sy); } private void scale(final Transform transform, final double delta) { transform.scale(delta); } private void translate(final Transform transform, final double tx, final double ty) { transform.translate(tx, ty); } private Viewport getViewPort() { return layer.getViewport(); } }