/* * 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.palette; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import com.google.gwt.logging.client.LogConfiguration; import org.kie.workbench.common.stunner.core.client.api.ShapeManager; 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.controls.builder.NodeBuilderControl; import org.kie.workbench.common.stunner.core.client.canvas.controls.toolbox.command.AbstractToolboxCommand; import org.kie.workbench.common.stunner.core.client.canvas.controls.toolbox.command.Context; import org.kie.workbench.common.stunner.core.client.canvas.util.CanvasHighlight; import org.kie.workbench.common.stunner.core.client.components.drag.NodeDragProxy; import org.kie.workbench.common.stunner.core.client.components.palette.Palette; import org.kie.workbench.common.stunner.core.client.components.palette.model.GlyphPaletteItem; import org.kie.workbench.common.stunner.core.client.components.palette.model.HasPaletteItems; import org.kie.workbench.common.stunner.core.client.components.palette.model.PaletteDefinitionBuilder; import org.kie.workbench.common.stunner.core.client.components.palette.model.definition.DefinitionsPalette; import org.kie.workbench.common.stunner.core.client.components.palette.model.definition.DefinitionsPaletteBuilder; import org.kie.workbench.common.stunner.core.client.components.palette.view.PaletteView; import org.kie.workbench.common.stunner.core.client.service.ClientFactoryService; import org.kie.workbench.common.stunner.core.client.service.ClientRuntimeError; import org.kie.workbench.common.stunner.core.graph.Edge; import org.kie.workbench.common.stunner.core.graph.Element; import org.kie.workbench.common.stunner.core.graph.Node; import org.kie.workbench.common.stunner.core.graph.content.definition.Definition; import org.kie.workbench.common.stunner.core.graph.processing.index.bounds.GraphBoundsIndexer; import org.kie.workbench.common.stunner.core.lookup.util.CommonLookups; public abstract class AbstractPaletteCommand<I> extends AbstractToolboxCommand<I> { private static Logger LOGGER = Logger.getLogger(AbstractPaletteCommand.class.getName()); private final I icon; protected final ClientFactoryService clientFactoryServices; protected final CommonLookups commonLookups; protected final ShapeManager shapeManager; protected final DefinitionsPaletteBuilder definitionsPaletteBuilder; protected final Palette<HasPaletteItems<? extends GlyphPaletteItem>> palette; protected final NodeDragProxy<AbstractCanvasHandler> nodeDragProxyFactory; protected final NodeBuilderControl<AbstractCanvasHandler> nodeBuilderControl; protected final GraphBoundsIndexer graphBoundsIndexer; protected AbstractCanvasHandler canvasHandler; protected CanvasHighlight canvasHighlight; protected Node<? extends Definition<Object>, ? extends Edge> sourceNode; protected boolean paletteVisible; protected String elementUUID; public AbstractPaletteCommand(final ClientFactoryService clientFactoryServices, final CommonLookups commonLookups, final ShapeManager shapeManager, final DefinitionsPaletteBuilder definitionsPaletteBuilder, final Palette<HasPaletteItems<? extends GlyphPaletteItem>> palette, final NodeDragProxy<AbstractCanvasHandler> nodeDragProxyFactory, final NodeBuilderControl<AbstractCanvasHandler> nodeBuilderControl, final GraphBoundsIndexer graphBoundsIndexer, final I icon) { this.clientFactoryServices = clientFactoryServices; this.commonLookups = commonLookups; this.shapeManager = shapeManager; this.definitionsPaletteBuilder = definitionsPaletteBuilder; this.palette = palette; this.nodeDragProxyFactory = nodeDragProxyFactory; this.nodeBuilderControl = nodeBuilderControl; this.graphBoundsIndexer = graphBoundsIndexer; this.icon = icon; this.paletteVisible = false; } protected abstract Set<String> getDefinitions(); protected abstract void onItemSelected(final Context<AbstractCanvasHandler> context, final String definitionId, final double x, final double y); @Override public I getIcon(final AbstractCanvasHandler context, final double width, final double height) { return icon; } // TODO: I18n. @Override public String getTitle() { return "- Empty title -"; } @Override @SuppressWarnings("unchecked") public void mouseEnter(final Context<AbstractCanvasHandler> context, final Element element) { super.mouseEnter(context, element); showPalette(context, element); } @Override public void click(final Context<AbstractCanvasHandler> context, final Element element) { super.click(context, element); if (paletteVisible) { clear(); } else { showPalette(context, element); } } @SuppressWarnings("unchecked") protected void showPalette(final Context<AbstractCanvasHandler> context, final Element element) { this.elementUUID = element.getUUID(); this.paletteVisible = true; this.canvasHandler = context.getCanvasHandler(); this.sourceNode = (Node<? extends Definition<Object>, ? extends Edge>) element; this.graphBoundsIndexer.setRootUUID(canvasHandler.getDiagram().getMetadata().getCanvasRootUUID()); final Set<String> allowedDefinitions = getDefinitions(); log(Level.FINE, "Allowed Definitions -> " + allowedDefinitions); if (null != allowedDefinitions && !allowedDefinitions.isEmpty()) { definitionsPaletteBuilder.build(allowedDefinitions, new PaletteDefinitionBuilder.Callback<DefinitionsPalette, ClientRuntimeError>() { @Override public void onSuccess(final DefinitionsPalette paletteDefinition) { initializeView(paletteDefinition, context); } @Override public void onError(final ClientRuntimeError error) { log(Level.SEVERE, error.toString()); } }); } } protected abstract void attachPaletteView(); @SuppressWarnings("unchecked") private void initializeView(final DefinitionsPalette paletteDefinition, final Context<AbstractCanvasHandler> context) { // Delegate to the builder control instance the current command manager. nodeBuilderControl.setCommandManagerProvider(context::getCommandManager); // Palette binding. beforeBindPalette(paletteDefinition, context); palette.bind(paletteDefinition) .onItemHover((id, mouseX, mouseY, itemX, itemY) -> AbstractPaletteCommand.this._onItemHover(context, id, mouseX, mouseY, itemX, itemY)) .onItemOut((id) -> AbstractPaletteCommand.this._onItemOut(context, id)) .onItemClick((id, mouseX, mouseY, itemX, itemY) -> AbstractPaletteCommand.this._onItemClick(context, id, mouseX, mouseY, itemX, itemY)) .onItemMouseDown((id, mouseX, mouseY, itemX, itemY) -> AbstractPaletteCommand.this._onItemMouseDown(context, id, mouseX, mouseY, itemX, itemY)); // Use the relative coordinates (x/y) as palette gets added into same canvas' layer as the toolbox. showPaletteViewAt(context.getX(), context.getY()); } protected void beforeBindPalette(final DefinitionsPalette paletteDefinition, final Context<AbstractCanvasHandler> context) { // Nothing to do by default. } protected void showPaletteViewAt(final double x, final double y) { getPaletteView().setX(x); getPaletteView().setY(y); attachPaletteView(); getPaletteView().show(); } public void clear() { this.nodeBuilderControl.setCommandManagerProvider(null); this.paletteVisible = false; this.elementUUID = null; getPaletteView().clear(); } private boolean _onItemClick(final Context<AbstractCanvasHandler> context, final String id, final double mouseX, final double mouseY, final double itemX, final double itemY) { // TODO return true; } private boolean _onItemHover(final Context<AbstractCanvasHandler> context, final String id, final double mouseX, final double mouseY, final double itemX, final double itemY) { canvasHandler.getAbstractCanvas().getView().setCursor(AbstractCanvas.Cursors.POINTER); return true; } private boolean _onItemOut(final Context<AbstractCanvasHandler> context, final String id) { canvasHandler.getAbstractCanvas().getView().setCursor(AbstractCanvas.Cursors.AUTO); return true; } @SuppressWarnings("unchecked") private boolean _onItemMouseDown(final Context<AbstractCanvasHandler> context, final String id, final double mouseX, final double mouseY, final double itemX, final double itemY) { onItemSelected(context, id, mouseX, mouseY); return true; } @Override public void destroy() { this.palette.destroy(); this.nodeDragProxyFactory.destroy(); this.nodeBuilderControl.setCommandManagerProvider(null); this.nodeBuilderControl.disable(); this.graphBoundsIndexer.destroy(); this.canvasHighlight.destroy(); this.canvasHandler = null; this.canvasHighlight = null; this.sourceNode = null; } protected abstract PaletteView getPaletteView(); private void log(final Level level, final String message) { if (LogConfiguration.loggingIsEnabled()) { LOGGER.log(level, message); } } }