/*
* 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.widgets.canvas.view;
import javax.annotation.PostConstruct;
import com.ait.lienzo.client.core.shape.GridLayer;
import com.ait.lienzo.client.core.shape.Layer;
import com.ait.lienzo.client.core.shape.Rectangle;
import com.ait.lienzo.client.core.shape.wires.WiresContainer;
import com.ait.lienzo.client.core.shape.wires.WiresLayer;
import com.ait.lienzo.client.core.shape.wires.WiresShape;
import com.ait.lienzo.shared.core.types.ColorName;
import com.google.gwt.dom.client.Style;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.IsWidget;
import org.kie.workbench.common.stunner.client.lienzo.canvas.LienzoGridLayerBuilder;
import org.kie.workbench.common.stunner.core.client.canvas.AbstractCanvas;
import org.kie.workbench.common.stunner.core.client.canvas.CanvasGrid;
import org.kie.workbench.common.stunner.core.client.shape.view.ShapeView;
public class CanvasView extends Composite implements AbstractCanvas.View<com.ait.lienzo.client.widget.LienzoPanel> {
private static final String Bg_COLOR = "#FFFFFF";
protected FlowPanel mainPanel = new FlowPanel();
protected FlowPanel toolsPanel = new FlowPanel();
protected com.ait.lienzo.client.widget.LienzoPanel panel;
protected Layer canvasLayer = new Layer();
protected org.kie.workbench.common.stunner.core.client.canvas.Layer layer;
/**
* Defines the usable area in the layer by stroking a rectangle for the
* defined canvas size. It provides visual feedback about the diagram's
* boundaries to the user once using mediators (zooming, panning, etc).
* It's added into the scene's top layer, so same transforms as the
* layer used by stunner are applied as well on this shape.
*/
protected final Rectangle decorator = new Rectangle(1,
1)
.setFillAlpha(0) // By default no decorator's fill.
.setStrokeAlpha(0) // By default no decorator's stroke.
.setStrokeWidth(1)
.setStrokeColor(ColorName.LIGHTGREY);
@PostConstruct
public void init() {
initWidget(mainPanel);
}
@Override
public AbstractCanvas.View show(final com.ait.lienzo.client.widget.LienzoPanel panel,
final int width,
final int height,
final org.kie.workbench.common.stunner.core.client.canvas.Layer layer) {
this.panel = panel;
this.layer = layer;
layer.initialize(canvasLayer);
panel.getElement().getStyle().setBackgroundColor(Bg_COLOR);
mainPanel.add(toolsPanel);
mainPanel.add(panel);
panel.getScene().add(canvasLayer);
decorator.setWidth(width);
decorator.setHeight(height);
if (null == decorator.getLayer() && null != canvasLayer.getScene()) {
canvasLayer.getScene().getTopLayer().add(decorator);
}
return this;
}
@Override
public AbstractCanvas.View add(final IsWidget widget) {
toolsPanel.add(widget);
return this;
}
@Override
public AbstractCanvas.View remove(final IsWidget widget) {
toolsPanel.remove(widget);
return this;
}
@Override
@SuppressWarnings("unchecked")
public AbstractCanvas.View addShape(final ShapeView<?> shapeView) {
layer.addShape(shapeView);
return this;
}
@Override
@SuppressWarnings("unchecked")
public AbstractCanvas.View removeShape(final ShapeView<?> shapeView) {
layer.removeShape(shapeView);
return this;
}
@Override
public AbstractCanvas.View addChildShape(final ShapeView<?> parent,
final ShapeView<?> child) {
final WiresShape parentShape = (WiresShape) parent;
final WiresShape childShape = (WiresShape) child;
return this.addChildShape(parentShape,
childShape);
}
protected AbstractCanvas.View addChildShape(final WiresShape parentShape,
final WiresShape childShape) {
parentShape.add(childShape);
return this;
}
@Override
public AbstractCanvas.View removeChildShape(final ShapeView<?> parent,
final ShapeView<?> child) {
final WiresShape parentShape = (WiresShape) parent;
final WiresShape childShape = (WiresShape) child;
return this.removeChildShape(parentShape,
childShape);
}
protected AbstractCanvas.View removeChildShape(final WiresShape parentShape,
final WiresShape childShape) {
parentShape.remove(childShape);
return this;
}
@Override
@SuppressWarnings("unchecked")
public AbstractCanvas.View dock(final ShapeView<?> parent,
final ShapeView<?> child) {
final WiresShape parentShape = (WiresShape) parent;
final WiresShape childShape = (WiresShape) child;
final WiresContainer parent1 = childShape.getParent();
if (null == parent1 || parent1 instanceof WiresLayer) {
layer.removeShape(childShape);
} else {
removeChildShape((ShapeView<?>) parent1,
child);
}
parentShape.add(childShape);
childShape.setDockedTo(parentShape);
return this;
}
@Override
public AbstractCanvas.View undock(final ShapeView<?> targetDockShape,
final ShapeView<?> childParent,
final ShapeView<?> child) {
final WiresShape newPraentShape = (WiresShape) childParent;
final WiresShape targetShape = (WiresShape) targetDockShape;
final WiresShape childShape = (WiresShape) child;
return this.undock(targetShape,
newPraentShape,
childShape);
}
@SuppressWarnings("unchecked")
protected AbstractCanvas.View undock(final WiresShape targetShape,
final WiresShape newPrentShape,
final WiresShape childShape) {
if (null != newPrentShape) {
newPrentShape.add(childShape);
} else {
layer.addShape(childShape);
}
targetShape.remove(childShape);
childShape.setDockedTo(null);
return this;
}
@Override
public double getAbsoluteX() {
return panel.getAbsoluteLeft();
}
@Override
public double getAbsoluteY() {
return panel.getAbsoluteTop();
}
@Override
public int getWidth() {
return panel.getWidth();
}
@Override
public int getHeight() {
return panel.getHeight();
}
@Override
public AbstractCanvas.View setGrid(final CanvasGrid grid) {
if (null != grid) {
GridLayer gridLayer = LienzoGridLayerBuilder.getLienzoGridFor(grid);
panel.setBackgroundLayer(gridLayer);
} else {
panel.setBackgroundLayer(null);
}
return this;
}
@Override
public AbstractCanvas.View setCursor(final AbstractCanvas.Cursors cursor) {
Style style = panel.getElement().getStyle();
switch (cursor) {
case AUTO:
style.setCursor(Style.Cursor.AUTO);
break;
case MOVE:
style.setCursor(Style.Cursor.MOVE);
break;
case TEXT:
style.setCursor(Style.Cursor.TEXT);
break;
case POINTER:
style.setCursor(Style.Cursor.POINTER);
break;
case NOT_ALLOWED:
// TODO: Use a good cursor.
style.setCursor(Style.Cursor.AUTO);
break;
case WAIT:
style.setCursor(Style.Cursor.WAIT);
break;
case CROSSHAIR:
style.setCursor(Style.Cursor.CROSSHAIR);
break;
}
return this;
}
@Override
public AbstractCanvas.View setDecoratorStrokeWidth(final double width) {
decorator.setStrokeWidth(width);
return this;
}
@Override
public AbstractCanvas.View setDecoratorStrokeAlpha(final double alpha) {
decorator.setStrokeAlpha(alpha);
return this;
}
@Override
public AbstractCanvas.View setDecoratorStrokeColor(final String color) {
decorator.setStrokeColor(color);
return this;
}
@Override
public org.kie.workbench.common.stunner.core.client.canvas.Layer getLayer() {
return layer;
}
@Override
public AbstractCanvas.View clear() {
layer.clear();
return this;
}
@Override
public void destroy() {
decorator.removeFromParent();
this.mainPanel.clear();
this.toolsPanel.clear();
this.layer.destroy();
this.canvasLayer.removeFromParent();
this.panel.removeFromParent();
this.mainPanel = null;
this.toolsPanel = null;
this.panel = null;
this.layer = null;
this.canvasLayer = null;
}
}