org.vectomatic.svg.edit.client.command.DndCommandFactory.java Source code

Java tutorial

Introduction

Here is the source code for org.vectomatic.svg.edit.client.command.DndCommandFactory.java

Source

/**********************************************
 * 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);
    //         }
    //      }
    //   }
}