001: /*******************************************************************************
002: * Copyright (c) 2005, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal.dnd;
011:
012: import org.eclipse.jface.util.Geometry;
013: import org.eclipse.swt.SWT;
014: import org.eclipse.swt.events.PaintEvent;
015: import org.eclipse.swt.events.PaintListener;
016: import org.eclipse.swt.graphics.Color;
017: import org.eclipse.swt.graphics.Point;
018: import org.eclipse.swt.graphics.RGB;
019: import org.eclipse.swt.graphics.Rectangle;
020: import org.eclipse.swt.widgets.Canvas;
021: import org.eclipse.swt.widgets.Composite;
022: import org.eclipse.swt.widgets.Control;
023: import org.eclipse.ui.themes.ColorUtil;
024:
025: /**
026: * Utility class that wraps a given control with a black 'border'. Moving the
027: * border control will cause the given control to move to stay within its bounds.
028: *
029: * @since 3.2
030: *
031: */
032: public class DragBorder {
033: // Controls
034: private Composite clientControl = null;
035: private Control dragControl = null;
036: private Canvas border = null;
037:
038: // Colors
039: private Color baseColor;
040: private Color hilightColor;
041: private boolean isHighlight;
042:
043: /**
044: * Construct a new DragBorder.
045: *
046: * @param client The client window that the border must stay within
047: * @param toDrag The control to be placed 'inside' the border
048: */
049: public DragBorder(Composite client, Control toDrag,
050: boolean provideFrame) {
051: clientControl = client;
052: dragControl = toDrag;
053: Point dragSize = toDrag.getSize();
054:
055: // Create a control large enough to 'contain' the dragged control
056: border = new Canvas(dragControl.getParent(), SWT.NONE);
057: border.setSize(dragSize.x + 2, dragSize.y + 2);
058:
059: // Use the SWT 'title' colors since they should always have a proper contrast
060: // and are 'related' (i.e. should look good together)
061: baseColor = border.getDisplay().getSystemColor(
062: SWT.COLOR_LIST_SELECTION);
063: RGB background = border.getDisplay().getSystemColor(
064: SWT.COLOR_LIST_BACKGROUND).getRGB();
065: RGB blended = ColorUtil.blend(baseColor.getRGB(), background);
066: hilightColor = new Color(border.getDisplay(), blended);
067:
068: // Ensure the border is visible and the control is 'above' it...
069: border.moveAbove(null);
070: dragControl.moveAbove(null);
071:
072: if (provideFrame) {
073: border.addPaintListener(new PaintListener() {
074: public void paintControl(PaintEvent e) {
075: if (isHighlight) {
076: e.gc.setForeground(hilightColor);
077: } else {
078: e.gc.setForeground(baseColor);
079: }
080:
081: // Draw a rectangle as our 'border'
082: Rectangle bb = border.getBounds();
083: e.gc.drawRectangle(0, 0, bb.width - 1,
084: bb.height - 1);
085: }
086: });
087: }
088: }
089:
090: /**
091: * Move the border (and its 'contained' control to a new position. The new
092: * position will be adjusted to lie entirely within the client area of the
093: * <code>clientControl</code>.
094: *
095: * @param newPos The new position for the border
096: * @param alignment The location of the cursor relative to the border being dragged.
097: * Current implementation only recognizes SWT.TOP & SWT.BOTTOM (which implies SWT.LEFT)
098: * and SWT.CENTER (which centers teh dragged border on the cursor.
099: */
100: public void setLocation(Point newPos, int alignment) {
101: // Move the border but ensure that it is still inside the Client area
102: if (alignment == SWT.CENTER) {
103: Point size = border.getSize();
104: border.setLocation(newPos.x - (size.x / 2), newPos.y
105: - (size.y / 2));
106: } else if (alignment == SWT.TOP) {
107: border.setLocation(newPos.x, newPos.y);
108: } else {
109: border.setLocation(newPos.x, newPos.y - border.getSize().y);
110: }
111:
112: // Force the control to remain inside the shell
113: Rectangle bb = border.getBounds();
114: Rectangle cr = clientControl.getClientArea();
115: Geometry.moveInside(bb, cr);
116:
117: // Ensure that the controls are the 'topmost' controls
118: border.moveAbove(null);
119: dragControl.moveAbove(null);
120:
121: // OK, now move the drag control and the border to their new locations
122: dragControl.setLocation(bb.x + 1, bb.y + 1);
123: border.setBounds(bb);
124: }
125:
126: /**
127: * Sets the hilight 'mode' for the control.
128: * @param highlight true if the border should be drawn as 'hilighted'
129: */
130: public void setHighlight(boolean highlight) {
131: isHighlight = highlight;
132: border.redraw();
133: }
134:
135: /**
136: * Dispose the controls owned by the border.
137: */
138: public void dispose() {
139: hilightColor.dispose();
140: border.dispose();
141: }
142:
143: /**
144: * @return The bounds of the border's control.
145: */
146: public Rectangle getBounds() {
147: return border.getBounds();
148: }
149: }
|