/* * 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.core.client.canvas.controls.toolbox.command.builder; import javax.enterprise.event.Observes; import javax.inject.Inject; import org.kie.workbench.common.stunner.core.client.api.ShapeManager; 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.canvas.Transform; import org.kie.workbench.common.stunner.core.client.canvas.controls.toolbox.command.Context; import org.kie.workbench.common.stunner.core.client.canvas.event.keyboard.KeyDownEvent; import org.kie.workbench.common.stunner.core.client.canvas.event.keyboard.KeyboardEvent; import org.kie.workbench.common.stunner.core.client.components.drag.DragProxyCallback; import org.kie.workbench.common.stunner.core.client.components.glyph.DefinitionGlyphTooltip; import org.kie.workbench.common.stunner.core.client.components.glyph.GlyphTooltip; import org.kie.workbench.common.stunner.core.client.service.ClientFactoryService; import org.kie.workbench.common.stunner.core.client.shape.factory.ShapeFactory; import org.kie.workbench.common.stunner.core.client.shape.view.glyph.Glyph; import org.kie.workbench.common.stunner.core.graph.Element; import org.kie.workbench.common.stunner.core.graph.processing.index.bounds.GraphBoundsIndexer; import static org.uberfire.commons.validation.PortablePreconditions.checkNotNull; public abstract class AbstractElementBuilderCommand<I> extends AbstractBuilderCommand<I> { private final ShapeManager shapeManager; private final DefinitionGlyphTooltip<?> glyphTooltip; private I iconView; private ShapeFactory factory; @Inject public AbstractElementBuilderCommand(final ClientFactoryService clientFactoryServices, final ShapeManager shapeManager, final DefinitionGlyphTooltip<?> glyphTooltip, final GraphBoundsIndexer graphBoundsIndexer) { super(clientFactoryServices, graphBoundsIndexer); this.shapeManager = shapeManager; this.glyphTooltip = glyphTooltip; } protected abstract String getGlyphDefinitionId(); @Override public void destroy() { super.destroy(); this.factory = null; this.iconView = null; } @Override @SuppressWarnings("unchecked") public I getIcon(final AbstractCanvasHandler context, final double width, final double height) { if (null == iconView) { final ShapeFactory factory = getFactory(context); // TODO: Review why glyphs result smaller than expected. Adding some padding pixels here. final Glyph<I> glyph = factory.glyph(getGlyphDefinitionId(), width + 6, height + 6); this.iconView = glyph.getGroup(); } return iconView; } @Override public void mouseEnter(final Context<AbstractCanvasHandler> context, final Element element) { super.mouseEnter(context, element); if (null != getFactory(context.getCanvasHandler())) { final Transform transform = context.getCanvasHandler().getCanvas().getLayer().getTransform(); final double ax = context.getCanvasHandler().getAbstractCanvas().getView().getAbsoluteX(); final double ay = context.getCanvasHandler().getAbstractCanvas().getView().getAbsoluteY(); // As tooltip is a floating view (not part of the canvas), need to transform the cartesian coordinates // using current transform attributes to obtain the right absolute position on the screen. final Point2D t = transform.transform(context.getX(), context.getY()); glyphTooltip.showTooltip(getGlyphDefinitionId(), ax + t.getX() + 20, ay + t.getY(), GlyphTooltip.Direction.WEST); } } @Override public void mouseExit(final Context<AbstractCanvasHandler> context, final Element element) { super.mouseExit(context, element); glyphTooltip.hide(); } protected ShapeFactory getFactory(final AbstractCanvasHandler context) { if (null == factory) { final String ssid = context.getDiagram().getMetadata().getShapeSetId(); factory = shapeManager.getShapeSet(ssid) .getShapeFactory(); } return factory; } @Override protected DragProxyCallback getDragProxyCallback(final Context<AbstractCanvasHandler> context, final Element element, final Element item) { return new DragProxyCallback() { @Override public void onStart(final int x1, final int y1) { AbstractElementBuilderCommand.this.onStart(context, element, item, x1, y1); } @Override public void onMove(final int x1, final int y1) { AbstractElementBuilderCommand.this.onMove(context, element, item, x1, y1); } @Override public void onComplete(final int x1, final int y1) { AbstractElementBuilderCommand.this.onComplete(context, element, item, x1, y1); } }; } @Override protected void onItemBuilt(final Context<AbstractCanvasHandler> context, final String uuid) { super.onItemBuilt(context, uuid); glyphTooltip.hide(); } protected void clearDragProxy() { getDragProxyFactory().clear(); } ShapeManager getShapeManager() { return shapeManager; } DefinitionGlyphTooltip<?> getGlyphTooltip() { return glyphTooltip; } /** * Listens for <code>ESC</code> key pressed - cancels the current drag/build operation. */ void onKeyDownEvent(final @Observes KeyDownEvent keyDownEvent) { checkNotNull("keyDownEvent", keyDownEvent); final KeyboardEvent.Key key = keyDownEvent.getKey(); if (null != key && KeyboardEvent.Key.ESC.equals(key)) { clearDragProxy(); } } }