| /******************************************************************************* |
| * Copyright (c) 2005, 2007 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.ui.internal.dnd; |
| |
| import org.eclipse.jface.util.Geometry; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.PaintEvent; |
| import org.eclipse.swt.events.PaintListener; |
| import org.eclipse.swt.graphics.Color; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.swt.graphics.RGB; |
| import org.eclipse.swt.graphics.Rectangle; |
| import org.eclipse.swt.widgets.Canvas; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.ui.themes.ColorUtil; |
| |
| /** |
| * Utility class that wraps a given control with a black 'border'. Moving the |
| * border control will cause the given control to move to stay within its bounds. |
| * |
| * @since 3.2 |
| * |
| */ |
| public class DragBorder { |
| // Controls |
| private Composite clientControl = null; |
| private Control dragControl = null; |
| private Canvas border = null; |
| |
| // Colors |
| private Color baseColor; |
| private Color hilightColor; |
| private boolean isHighlight; |
| |
| /** |
| * Construct a new DragBorder. |
| * |
| * @param client The client window that the border must stay within |
| * @param toDrag The control to be placed 'inside' the border |
| */ |
| public DragBorder(Composite client, Control toDrag, boolean provideFrame) { |
| clientControl = client; |
| dragControl = toDrag; |
| Point dragSize = toDrag.getSize(); |
| |
| // Create a control large enough to 'contain' the dragged control |
| border = new Canvas(dragControl.getParent(), SWT.NONE); |
| border.setSize(dragSize.x+2, dragSize.y+2); |
| |
| // Use the SWT 'title' colors since they should always have a proper contrast |
| // and are 'related' (i.e. should look good together) |
| baseColor = border.getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION); |
| RGB background = border.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND).getRGB(); |
| RGB blended = ColorUtil.blend(baseColor.getRGB(), background); |
| hilightColor = new Color(border.getDisplay(), blended); |
| |
| // Ensure the border is visible and the control is 'above' it... |
| border.moveAbove(null); |
| dragControl.moveAbove(null); |
| |
| if (provideFrame) { |
| border.addPaintListener(new PaintListener() { |
| public void paintControl(PaintEvent e) { |
| if (isHighlight) { |
| e.gc.setForeground(hilightColor); |
| } |
| else { |
| e.gc.setForeground(baseColor); |
| } |
| |
| // Draw a rectangle as our 'border' |
| Rectangle bb = border.getBounds(); |
| e.gc.drawRectangle(0,0,bb.width-1, bb.height-1); |
| } |
| }); |
| } |
| } |
| |
| |
| /** |
| * Move the border (and its 'contained' control to a new position. The new |
| * position will be adjusted to lie entirely within the client area of the |
| * <code>clientControl</code>. |
| * |
| * @param newPos The new position for the border |
| * @param alignment The location of the cursor relative to the border being dragged. |
| * Current implementation only recognizes SWT.TOP & SWT.BOTTOM (which implies SWT.LEFT) |
| * and SWT.CENTER (which centers teh dragged border on the cursor. |
| */ |
| public void setLocation(Point newPos, int alignment) { |
| // Move the border but ensure that it is still inside the Client area |
| if (alignment == SWT.CENTER) { |
| Point size = border.getSize(); |
| border.setLocation(newPos.x - (size.x/2), newPos.y - (size.y/2)); |
| } |
| else if (alignment == SWT.TOP) { |
| border.setLocation(newPos.x, newPos.y); |
| } else { |
| border.setLocation(newPos.x, newPos.y - border.getSize().y); |
| } |
| |
| // Force the control to remain inside the shell |
| Rectangle bb = border.getBounds(); |
| Rectangle cr = clientControl.getClientArea(); |
| Geometry.moveInside(bb,cr); |
| |
| // Ensure that the controls are the 'topmost' controls |
| border.moveAbove(null); |
| dragControl.moveAbove(null); |
| |
| // OK, now move the drag control and the border to their new locations |
| dragControl.setLocation(bb.x+1, bb.y+1); |
| border.setBounds(bb); |
| } |
| |
| /** |
| * Sets the hilight 'mode' for the control. |
| * @param highlight true if the border should be drawn as 'hilighted' |
| */ |
| public void setHighlight(boolean highlight) { |
| isHighlight = highlight; |
| border.redraw(); |
| } |
| |
| /** |
| * Dispose the controls owned by the border. |
| */ |
| public void dispose() { |
| hilightColor.dispose(); |
| border.dispose(); |
| } |
| |
| |
| /** |
| * @return The bounds of the border's control. |
| */ |
| public Rectangle getBounds() { |
| return border.getBounds(); |
| } |
| } |