Package org.dyno.visual.swing.editors

Source Code of org.dyno.visual.swing.editors.OutlineViewDnD

/************************************************************************************
* Copyright (c) 2008 William Chen.                                                 *
*                                                                                  *
* All rights reserved. This program and the accompanying materials are made        *
* available under the terms of the Eclipse Public License v1.0 which accompanies   *
* this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html *
*                                                                                  *
* Use is subject to the terms of Eclipse Public License v1.0.                      *
*                                                                                  *
* Contributors:                                                                    *
*     William Chen - initial API and implementation.                               *
************************************************************************************/

package org.dyno.visual.swing.editors;

import java.awt.Component;
import java.awt.Container;

import javax.swing.SwingUtilities;

import org.dyno.visual.swing.designer.VisualDesigner;
import org.dyno.visual.swing.plugin.spi.CompositeAdapter;
import org.dyno.visual.swing.plugin.spi.WidgetAdapter;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.dnd.TreeDropTargetEffect;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;

class OutlineViewDnD extends DropTargetAdapter implements DragSourceListener {
  private TreeViewer treeView;
  private Tree tree;
  private TreeItem[] treeItems;
  private Display display;
  private VisualDesigner designer;

  public OutlineViewDnD(VisualDesigner designer) {
    this.designer = designer;
  }

  public void attach(TreeViewer treeView) {
    this.treeView = treeView;
    this.tree = treeView.getTree();
    display = tree.getDisplay();

    Transfer[] types = new Transfer[] { new JComponentTransfer() };
    int operations = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_LINK;
    final DragSource source = new DragSource(tree, operations);
    source.setTransfer(types);
    treeItems = new TreeItem[1];
    source.addDragListener(this);

    DropTarget target = new DropTarget(tree, operations);
    target.setDropTargetEffect(new MyDropTargetEffect(tree));
    target.setTransfer(types);
    target.addDropListener(this);
  }

  public void dragFinished(DragSourceEvent event) {
    if (event.detail == DND.DROP_MOVE) {
      for (TreeItem item : treeItems)
        item.dispose();
      treeView.refresh();
      designer.repaint();
      designer.publishSelection();
    }
    treeItems = null;
  }

  public void dragSetData(DragSourceEvent event) {
    Component[] components = new Component[treeItems.length];
    for (int i = 0; i < treeItems.length; i++) {
      components[i] = (Component) treeItems[i].getData();
    }
    event.data = components;
  }

  public void dragStart(DragSourceEvent event) {
    TreeItem[] selection = tree.getSelection();
    if (selection.length > 0) {
      Container parent = null;
      for (TreeItem item : selection) {
        Object object = item.getData();
        if (!(object instanceof Component)) {
          event.doit = false;
          return;
        } else {
          Component comp = (Component) object;
          WidgetAdapter adapter = WidgetAdapter
              .getWidgetAdapter(comp);
          if (adapter.isRoot()) {
            event.doit = false;
            return;
          } else {
            if (parent == null)
              parent = comp.getParent();
            else if (parent != comp.getParent()) {
              event.doit = false;
              return;
            }
          }
        }
      }
      treeItems = selection;
      event.doit = true;
    } else {
      event.doit = false;
    }
  }

  public void dragOver(DropTargetEvent event) {
    event.feedback = DND.FEEDBACK_EXPAND | DND.FEEDBACK_SCROLL;
    if (event.item != null) {
      TreeItem item = (TreeItem) event.item;
      Point pt = display.map(null, tree, event.x, event.y);
      Rectangle bounds = item.getBounds();
      if (pt.y < bounds.y + bounds.height / 4) {
        event.feedback |= DND.FEEDBACK_INSERT_BEFORE;
      } else if (pt.y > bounds.y + 3 * bounds.height / 4) {
        event.feedback |= DND.FEEDBACK_INSERT_AFTER;
      } else {
        event.feedback |= DND.FEEDBACK_SELECT;
      }
    }
  }

  private void moveToSelectedNode(CompositeAdapter parent_adapter,
      Component target_comp, DropTargetEvent event, Component[] components) {
    if (parent_adapter.getWidget() == target_comp) {
      event.detail = DND.DROP_NONE;
    } else {
      WidgetAdapter target_adapter = WidgetAdapter
          .getWidgetAdapter(target_comp);
      CompositeAdapter target_parent = target_adapter.getParentAdapter();
      if (target_parent == parent_adapter) {
        if (!(target_adapter instanceof CompositeAdapter)) {
          event.detail = DND.DROP_NONE;
          return;
        }
      }
      for (Component component : components) {
        if (component == target_comp) {
          event.detail = DND.DROP_NONE;
          return;
        }
        if (SwingUtilities.isDescendingFrom(target_comp, component)) {
          event.detail = DND.DROP_NONE;
          return;
        }
      }
      for (Component component : components) {
        parent_adapter.removeChild(component);
        if (target_adapter instanceof CompositeAdapter)
          ((CompositeAdapter) target_adapter).addChild(component);
      }
      target_adapter.getRootAdapter().getWidget().validate();
    }
  }

  private void moveBeforeSelectedNode(CompositeAdapter parent_adapter,
      Component target_comp, DropTargetEvent event, Component[] components) {
    if (parent_adapter.getWidget() == target_comp) {
      event.detail = DND.DROP_NONE;
    } else {
      WidgetAdapter target_adapter = WidgetAdapter
          .getWidgetAdapter(target_comp);
      CompositeAdapter target_parent = target_adapter.getParentAdapter();
      for (Component component : components) {
        if (component == target_comp) {
          event.detail = DND.DROP_NONE;
          return;
        }
        if (SwingUtilities.isDescendingFrom(target_comp, component)) {
          event.detail = DND.DROP_NONE;
          return;
        }
      }
      for (Component component : components) {
        parent_adapter.removeChild(component);
        target_parent.addBefore(target_comp, component);
      }
    }
  }

  private void moveAfterSelectedNode(CompositeAdapter parent_adapter,
      Component target_comp, DropTargetEvent event, Component[] components) {
    if (parent_adapter.getWidget() == target_comp) {
      event.detail = DND.DROP_NONE;
    } else {
      WidgetAdapter target_adapter = WidgetAdapter
          .getWidgetAdapter(target_comp);
      CompositeAdapter target_parent = target_adapter.getParentAdapter();
      for (Component component : components) {
        if (component == target_comp) {
          event.detail = DND.DROP_NONE;
          return;
        }
        if (SwingUtilities.isDescendingFrom(target_comp, component)) {
          event.detail = DND.DROP_NONE;
          return;
        }
      }
      for (Component component : components) {
        parent_adapter.removeChild(component);
        target_parent.addAfter(target_comp, component);
      }
    }
  }

  public void drop(DropTargetEvent event) {

    if (event.data == null) {
      event.detail = DND.DROP_NONE;
      return;
    } else if (event.item == null) {
      event.detail = DND.DROP_NONE;
    } else {
      TreeItem target_item = (TreeItem) event.item;
      Object data = target_item.getData();
      if (!(data instanceof Component)) {
        event.detail = DND.DROP_NONE;
      } else {
        Component[] components = (Component[]) event.data;
        if (components.length == 0) {
          event.detail = DND.DROP_NONE;
        } else {
          Component first = components[0];
          WidgetAdapter first_adapter = WidgetAdapter
              .getWidgetAdapter(first);
          CompositeAdapter parent_adapter = first_adapter
              .getParentAdapter();
          if ((feedback & DND.FEEDBACK_SELECT) != 0) {
            moveToSelectedNode(parent_adapter, target_comp, event,
                components);
          } else if ((feedback & DND.FEEDBACK_INSERT_BEFORE) != 0) {
            moveBeforeSelectedNode(parent_adapter, target_comp,
                event, components);
          } else if ((feedback & DND.FEEDBACK_INSERT_AFTER) != 0) {
            moveAfterSelectedNode(parent_adapter, target_comp,
                event, components);
          } else {
            event.detail = DND.DROP_NONE;
          }
        }
      }
    }
  }

  private int feedback;
  private Component target_comp;

  private class MyDropTargetEffect extends TreeDropTargetEffect {
    public MyDropTargetEffect(Tree tree) {
      super(tree);
    }

    @Override
    public void dragOver(DropTargetEvent event) {
      feedback = event.feedback;
      if (event.item.getData() instanceof Component)
        target_comp = (Component) event.item.getData();
      super.dragOver(event);
    }
  }
}

TOP

Related Classes of org.dyno.visual.swing.editors.OutlineViewDnD

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.