/* * Copyright 2015 JBoss, by Red Hat, Inc * * 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.uberfire.ext.wires.core.scratchpad.client.canvas; import javax.annotation.PostConstruct; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.enterprise.event.Observes; import javax.inject.Inject; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.IsWidget; import org.uberfire.client.annotations.WorkbenchMenu; import org.uberfire.client.annotations.WorkbenchPartTitle; import org.uberfire.client.annotations.WorkbenchPartView; import org.uberfire.client.annotations.WorkbenchScreen; import org.uberfire.ext.wires.core.api.containers.ContainerManager; import org.uberfire.ext.wires.core.api.containers.RequiresContainerManager; import org.uberfire.ext.wires.core.api.containers.WiresContainer; import org.uberfire.ext.wires.core.api.events.ClearEvent; import org.uberfire.ext.wires.core.api.events.ShapeAddedEvent; import org.uberfire.ext.wires.core.api.events.ShapeDeletedEvent; import org.uberfire.ext.wires.core.api.events.ShapeDragCompleteEvent; import org.uberfire.ext.wires.core.api.events.ShapeDragPreviewEvent; import org.uberfire.ext.wires.core.api.events.ShapeSelectedEvent; import org.uberfire.ext.wires.core.api.shapes.WiresBaseShape; import org.uberfire.ext.wires.core.api.shapes.WiresShape; import org.uberfire.ext.wires.core.client.canvas.WiresCanvas; import org.uberfire.mvp.Command; import org.uberfire.workbench.model.menu.MenuFactory; import org.uberfire.workbench.model.menu.Menus; @SuppressWarnings("unused") @Dependent @WorkbenchScreen(identifier = "WiresScratchPadScreen") public class WiresScratchPadScreen extends WiresCanvas implements ContainerManager { @Inject private Event<ClearEvent> clearEvent; @Inject private Event<ShapeSelectedEvent> shapeSelectedEvent; @Inject private Event<ShapeAddedEvent> shapeAddedEvent; @Inject private Event<ShapeDeletedEvent> shapeDeletedEvent; private Menus menus; private WiresScratchPadDropContext dropContext = new WiresScratchPadDropContext(); @PostConstruct public void setup() { this.menus = MenuFactory .newTopLevelMenu("Clear grid") .respondsWith(new Command() { @Override public void execute() { clear(); } }) .endMenu() .newTopLevelMenu("Delete selected") .respondsWith(new Command() { @Override public void execute() { if (isShapeSelected()) { deleteShape(getSelectedShape()); } } }) .endMenu() .newTopLevelMenu("Clear selection") .respondsWith(new Command() { @Override public void execute() { if (isShapeSelected()) { clearSelection(); menus.getItems().get(1).setEnabled(false); menus.getItems().get(2).setEnabled(false); } } }) .endMenu() .build(); menus.getItems().get(0).setEnabled(false); menus.getItems().get(1).setEnabled(false); menus.getItems().get(2).setEnabled(false); } @WorkbenchPartTitle @Override public String getTitle() { return "Canvas"; } @WorkbenchPartView public IsWidget getView() { return this; } @WorkbenchMenu public Menus getMenus() { return menus; } @Override public void selectShape(final WiresBaseShape shape) { shapeSelectedEvent.fire(new ShapeSelectedEvent(shape)); } public void onShapeSelected(@Observes ShapeSelectedEvent event) { super.selectShape(event.getShape()); menus.getItems().get(1).setEnabled(isShapeSelected()); menus.getItems().get(2).setEnabled(isShapeSelected()); } @Override public void deselectShape(final WiresBaseShape shape) { super.deselectShape(shape); menus.getItems().get(1).setEnabled(isShapeSelected()); menus.getItems().get(2).setEnabled(isShapeSelected()); } public void onDragPreviewHandler(@Observes ShapeDragPreviewEvent shapeDragPreviewEvent) { //Only Shapes that require a ContainerManager can be dropped into Containers if (!(shapeDragPreviewEvent.getShape() instanceof RequiresContainerManager)) { dropContext.setContext(null); return; } //Find a Container to drop the Shape into final double cx = getX(shapeDragPreviewEvent.getX()); final double cy = getY(shapeDragPreviewEvent.getY()); final WiresContainer container = getContainer(cx, cy); dropContext.setContext(container); canvasLayer.batch(); } public void onDragCompleteHandler(@Observes ShapeDragCompleteEvent shapeDragCompleteEvent) { final WiresBaseShape wiresShape = shapeDragCompleteEvent.getShape(); //If there's no Shape to add then exit if (wiresShape == null) { return; } //Get Shape's co-ordinates relative to the Canvas final double cx = getX(shapeDragCompleteEvent.getX()); final double cy = getY(shapeDragCompleteEvent.getY()); //If the Shape was dropped outside the bounds of the Canvas then exit if (cx < 0 || cy < 0) { return; } if (cx > getOffsetWidth() || cy > getOffsetHeight()) { return; } //Add Shape to Canvas wiresShape.setX(cx); wiresShape.setY(cy); //If we're adding the Shape to a Container notify the Container of a new child. We cannot add Shape //to the Container's underlying (impl) Group (which would be ideal) as we can no longer select the //child separately from the Group. We therefore just keep a reference to children in the Container //and move them when we move the Container final WiresContainer container = dropContext.getContext(); if (container != null) { container.attachShape(wiresShape); container.setHover(false); } addShape(wiresShape); //Enable clearing of Canvas now a Shape has been added menus.getItems().get(0).setEnabled(true); //Notify other Panels of a Shape being added shapeAddedEvent.fire(new ShapeAddedEvent(wiresShape)); } private double getX(double xShapeEvent) { return xShapeEvent - getAbsoluteLeft(); } private double getY(double yShapeEvent) { return yShapeEvent - getAbsoluteTop(); } @Override public void clear() { if (Window.confirm("Are you sure to clean the canvas?")) { clearEvent.fire(new ClearEvent()); } } public void onClear(@Observes ClearEvent event) { super.clear(); menus.getItems().get(0).setEnabled(false); menus.getItems().get(1).setEnabled(false); menus.getItems().get(2).setEnabled(false); } @Override public void deleteShape(final WiresBaseShape shape) { if (Window.confirm("Are you sure to remove the selected shape?")) { shapeDeletedEvent.fire(new ShapeDeletedEvent(shape)); } } @Override public void forceDeleteShape(final WiresBaseShape shape) { shapeDeletedEvent.fire(new ShapeDeletedEvent(shape)); } public void onShapeDeleted(@Observes ShapeDeletedEvent event) { super.deleteShape(event.getShape()); menus.getItems().get(0).setEnabled(getShapesInCanvas().size() > 0); menus.getItems().get(1).setEnabled(isShapeSelected()); menus.getItems().get(2).setEnabled(isShapeSelected()); } @Override public void addShape(final WiresBaseShape shape) { super.addShape(shape); //Attach relevant handlers if (shape instanceof RequiresContainerManager) { ((RequiresContainerManager) shape).setContainerManager(this); } } @Override public WiresContainer getContainer(final double cx, final double cy) { WiresContainer container = null; for (WiresShape ws : getShapesInCanvas()) { if (ws instanceof WiresContainer) { final WiresContainer wc = (WiresContainer) ws; wc.setHover(false); if (wc.contains(cx, cy)) { wc.setHover(true); container = wc; } } } return container; } }