Java tutorial
/********************************************** * Copyright (C) 2011 Lukas Laag * This file is part of svgreal. * * svgreal is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * svgreal is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with svgreal. If not, see http://www.gnu.org/licenses/ **********************************************/ package org.vectomatic.svg.edit.client.command; import java.util.List; import org.vectomatic.svg.edit.client.command.dnd.DndCopyHandler; import org.vectomatic.svg.edit.client.command.dnd.DndLinkHandler; import org.vectomatic.svg.edit.client.command.dnd.DndMoveHandler; import org.vectomatic.svg.edit.client.command.dnd.IDndHandler; import org.vectomatic.svg.edit.client.event.KeyPressProcessor; import org.vectomatic.svg.edit.client.event.KeyUpProcessor; import org.vectomatic.svg.edit.client.gxt.widget.DNDGhost; import org.vectomatic.svg.edit.client.model.ModelConstants; import org.vectomatic.svg.edit.client.model.svg.SVGElementModel; import com.extjs.gxt.ui.client.dnd.StatusProxy; import com.extjs.gxt.ui.client.event.ComponentEvent; import com.extjs.gxt.ui.client.event.DNDEvent; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Style; import com.google.gwt.dom.client.Style.Position; import com.google.gwt.dom.client.Style.Unit; /** * Base class for drag and drop command factories * @author laaglu */ public class DndCommandFactory extends CommandFactoryBase implements KeyPressProcessor, KeyUpProcessor { /** * Enum to represent the drop gestures */ public enum DropGesture { /** * The source is released precisely on the target */ OnNode, /** * The source is released slightly before the target */ BeforeNode, /** * The source is released slightly after the target */ AfterNode } /** * Default handler for drag and drop events */ private static IDndHandler defaultHandler = new DndMoveHandler(); /** * Handlers for drag and drop events */ private static IDndHandler[] handlers = new IDndHandler[] { new DndCopyHandler(), new DndLinkHandler(), defaultHandler }; /** * The handler which currently processes the drag interactions */ private IDndHandler currentHandler; /** * The drag and drop proxy */ StatusProxy proxy; /** * To graphically represent the drag operation */ private DNDGhost dndGhost; /** * The drag source elements */ private List<SVGElementModel> sourceElements; /** * The drop target over which the user has last move the mouse */ private SVGElementModel targetElement; /** * True if the current drop target is valid */ boolean validTarget; @SuppressWarnings("serial") public static final IFactoryInstantiator<DndCommandFactory> INSTANTIATOR = new FactoryInstantiatorBase<DndCommandFactory>( ModelConstants.INSTANCE.dndCmdFactory(), ModelConstants.INSTANCE.dndCmdFactoryDesc()) { @Override public DndCommandFactory create() { return new DndCommandFactory(); } }; @Override public IFactoryInstantiator<?> getInstantiator() { return INSTANTIATOR; } @Override public void start(Object requester) { GWT.log("DndCommandFactory.start(" + requester + ")"); super.start(requester); updateStatus(ModelConstants.INSTANCE.dndCmdFactory1()); } /** * Returns true if the drag start event comes from a valid drag source * @param event a drag start event * @return true if the drag start event comes from a valid drag source */ public boolean isValidSource(DNDEvent event, List<SVGElementModel> sourceElements) { targetElement = null; validTarget = false; this.sourceElements = sourceElements; for (IDndHandler handler : handlers) { if (handler.isValidSource(event, sourceElements)) { dndGhost = new DNDGhost(sourceElements, event); proxy = event.getStatus(); proxy.update(dndGhost.getElement()); targetElement = null; setHandler(handler); /* * The drag and drop elements in GXT are positionned as follows: * div container (x-dd-drag-proxy) * div icon (x-dd-drop-icon) * div proxy (x-dd-drag-ghost) * div ghost (custom ghost) * * x-dd-drag-ghost needs to be altered to be made absolute * in order to support custom ghost with absolute positioning */ Style proxyStyle = dndGhost.getElement().getParentElement().getStyle(); proxyStyle.setPosition(Position.ABSOLUTE); proxyStyle.setLeft(0, Unit.PX); proxyStyle.setRight(0, Unit.PX); proxyStyle.setTop(0, Unit.PX); proxyStyle.setBottom(0, Unit.PX); return true; } } return false; } public boolean isValidDropTarget(SVGElementModel element) { if (targetElement != element) { targetElement = element; validTarget = currentHandler.isValidTarget(sourceElements, targetElement); GWT.log("isValidDropTarget(" + targetElement + ") = " + validTarget); } return validTarget; } public void processDragAndDrop(DropGesture dropGesture) { GWT.log("processDragAndDrop(" + sourceElements + ", " + targetElement + "," + dropGesture + ") = " + validTarget); // TODO // ignore useless drag and drops: // drag last item of a folder in its parent // drag an item before of after itself currentHandler.createCommands(sourceElements, targetElement, dropGesture); currentHandler = null; } @Override public boolean processKeyPress(ComponentEvent event) { for (IDndHandler handler : handlers) { if (handler.getKeyCode() == event.getKeyCode()) { setHandler(handler); return true; } } return false; } @Override public boolean processKeyUp(ComponentEvent event) { for (IDndHandler handler : handlers) { if (handler.getKeyCode() == event.getKeyCode()) { setHandler(defaultHandler); return true; } } return false; } private void setHandler(IDndHandler handler) { if (handler != currentHandler) { currentHandler = handler; dndGhost.update(currentHandler); proxy.setStatus(currentHandler.isValidTarget(sourceElements, targetElement)); } } // /** // * Extracts the SVG models from a drag and drop event // * @param event the event // * @return the SVG models associated to the event // */ // public static List<SVGElementModel> getData(DNDEvent event) { // List<TreeStoreModel> storeModels = event.getData(); // ArrayList<SVGElementModel> svgModels = new ArrayList<SVGElementModel>(); // for (TreeStoreModel storeModel : storeModels) { // svgModels.add((SVGElementModel) storeModel.getModel()); // } // return svgModels; // } // // // static private List<String> eventLog; // static public void logDNDEvent(String origin, DNDEvent event) { // List<String> strList = new ArrayList<String>(); // strList.add("=================== DNDListener ====================="); // strList.add("origin = " + origin); // EventType type = event.getType(); // if (type == Events.DragStart) { // strList.add("type = DragStart"); // } else if (type == Events.DragEnter) { // strList.add("type = DragEnter"); // } else if (type == Events.DragLeave) { // strList.add("type = DragLeave"); // } else if (type == Events.DragMove) { // strList.add("type = DragMove"); // } else if (type == Events.Drop) { // strList.add("type = Drop"); // } // strList.add("component = " + event.getComponent()); // strList.add("data = " + DndHandlerBase.getSourceElementNames(getData(event))); // strList.add("operation = " + event.getOperation()); // strList.add("source = " + event.getSource()); // DragSource dragSource = event.getDragSource(); // if (dragSource instanceof SVGTreePanelDragSource) { // SVGTreePanelDragSource source = (SVGTreePanelDragSource)dragSource; // strList.add("sourceModel = " + source.getSvgModel()); // } // DropTarget dropTarget = event.getDropTarget(); // if (dropTarget instanceof SVGTreePanelDropTarget) { // SVGTreePanelDropTarget target = (SVGTreePanelDropTarget)dropTarget; // strList.add("targetModel = " + target.getSvgModel()); // SVGElementModel activeItem = target.getActiveItem(); // if (activeItem != null) { // strList.add("activeItem = " + activeItem.get(SVGConstants.SVG_TITLE_TAG)); // } // SVGElementModel appendItem = target.getActiveItem(); // if (appendItem != null) { // strList.add("appendItem = " + appendItem.get(SVGConstants.SVG_TITLE_TAG)); // } // } // if (!strList.equals(eventLog)) { // eventLog = strList; // for(String str : eventLog) { // GWT.log(str); // } // } // } }