| /******************************************************************************* |
| * Copyright (c) 2013 IBM Corporation and others. |
| * 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 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.e4.ui.workbench.addons.dndaddon; |
| |
| import org.eclipse.jface.util.Geometry; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.swt.graphics.Rectangle; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.Shell; |
| |
| class DragAndDropUtil { |
| public static final String IGNORE_AS_DROP_TARGET = "ignore_as_drop_target"; //$NON-NLS-1$ |
| |
| /** |
| * Shorthand method. Returns the bounding rectangle for the given control, |
| * in display coordinates. |
| * |
| * @param boundsControl |
| * the control whose bounds are to be computed |
| * @return the bounds of the given control in display coordinates |
| */ |
| public static Rectangle getDisplayBounds(Control boundsControl) { |
| Control parent = boundsControl.getParent(); |
| if (parent == null || boundsControl instanceof Shell) { |
| return boundsControl.getBounds(); |
| } |
| |
| return Geometry.toDisplay(parent, boundsControl.getBounds()); |
| } |
| |
| /** |
| * Finds and returns the most specific SWT control at the given location. |
| * (Note: this does a DFS on the SWT widget hierarchy, which can be slow). |
| * Any invisible control or control tagged with IGNORE_AS_DROP_TARGET will |
| * be ignored by this method. |
| * |
| * @param displayToSearch |
| * the display to search for potential controls |
| * @param locationToFind |
| * the position, in display coordinates, to be located |
| * @return the most specific SWT control at the given location |
| */ |
| public static Control findControl(Display displayToSearch, Point locationToFind) { |
| Shell[] shells = displayToSearch.getShells(); |
| |
| return findControl(shells, locationToFind); |
| } |
| |
| /** |
| * Searches the given list of controls for a control containing the given |
| * point. If the array contains any composites, those composites will be |
| * recursively searched to find the most specific child that contains the |
| * point. Any invisible control or control tagged with IGNORE_AS_DROP_TARGET |
| * will be ignored by this method. |
| * |
| * @param toSearch |
| * an array of controls to be searched for potential matches |
| * @param locationToFind |
| * a point (in display coordinates) |
| * @return the most specific Control that overlaps the given point, or null |
| * if none |
| */ |
| public static Control findControl(Control[] toSearch, Point locationToFind) { |
| for (int idx = toSearch.length - 1; idx >= 0; idx--) { |
| Control next = toSearch[idx]; |
| |
| if (next.getData(IGNORE_AS_DROP_TARGET) != null) { |
| continue; |
| } |
| |
| if (!next.isDisposed() && next.isVisible()) { |
| Rectangle bounds = getDisplayBounds(next); |
| |
| if (bounds.contains(locationToFind)) { |
| if (next instanceof Composite) { |
| Control result = findControl((Composite) next, locationToFind); |
| |
| if (result != null) { |
| return result; |
| } |
| } |
| |
| return next; |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| /** |
| * Finds the control at the given location. Any invisible control or control |
| * tagged with IGNORE_AS_DROP_TARGET will be ignored by this method. |
| * |
| * @param toSearch |
| * the composite to be searched for potential matches. |
| * @param locationToFind |
| * location (in display coordinates) |
| * @return the control at the given location |
| */ |
| public static Control findControl(Composite toSearch, Point locationToFind) { |
| Control[] children = toSearch.getChildren(); |
| |
| return findControl(children, locationToFind); |
| } |
| } |