001: /*******************************************************************************
002: * Copyright (c) 2005, 2006 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.swt.SWT;
013: import org.eclipse.swt.graphics.Color;
014: import org.eclipse.swt.graphics.RGB;
015: import org.eclipse.swt.graphics.Rectangle;
016: import org.eclipse.swt.widgets.Canvas;
017: import org.eclipse.swt.widgets.Composite;
018: import org.eclipse.ui.themes.ColorUtil;
019:
020: /**
021: * This class provides 'insertion' feedback to the User. It can be used to draw a
022: * 'bracket' based on the trim area's rectangle.
023: *
024: * @since 3.2
025: */
026: public class InsertCaret {
027: // Constants
028: private static final int width = 6; // the handle's 'thickness'
029: private static final int pctInset = 10; // The percentage of the area left at each 'end'
030:
031: // Control info
032: private Canvas caretControl;
033: private Canvas end1;
034: private Canvas end2;
035:
036: // Colors
037: private Color baseColor;
038: private Color hilightColor;
039: private boolean isHighlight;
040:
041: /**
042: * Creates an affordance to indicate that the given trim area is a valid location for the
043: * trim being dragged.
044: *
045: * @param windowComposite The window to create the affordance as a child of
046: * @param trimRect The rectangle to show the affordance for
047: * @param swtSide The 'side' that the rectangle is on
048: * @param threshold The amount to offfset the affordance by
049: */
050: public InsertCaret(Composite parent, Rectangle trimRect,
051: int swtSide, int threshold) {
052: // Use the SWT 'title' colors since they should always have a proper contrast
053: // and are 'related' (i.e. should look good together)
054: baseColor = parent.getDisplay().getSystemColor(
055: SWT.COLOR_LIST_SELECTION);
056: RGB background = parent.getDisplay().getSystemColor(
057: SWT.COLOR_LIST_BACKGROUND).getRGB();
058: RGB blended = ColorUtil.blend(baseColor.getRGB(), background);
059: hilightColor = new Color(parent.getDisplay(), blended);
060:
061: //Create the caret control
062: createControl(parent, trimRect, swtSide, threshold);
063: }
064:
065: /**
066: * Creates a control to show the 'area valid' affordance. The current implementation creates a
067: * simple rect half the length of the rect, centered and offset by the 'threshold' value.
068: *
069: * @param parent The control to used as the parent of the affordance control
070: * @param trimRect The trim rectangle
071: * @param swtSide The SWT side that the trim is on
072: * @param threshold The offset value
073: */
074: private void createControl(Composite parent, Rectangle trimRect,
075: int swtSide, int threshold) {
076: int hDelta = trimRect.width / pctInset;
077: int vDelta = trimRect.height / pctInset;
078: caretControl = new Canvas(parent.getShell(), SWT.BORDER);
079:
080: end1 = new Canvas(parent.getShell(), SWT.BORDER);
081: end1.setSize(width, width);
082: end2 = new Canvas(parent.getShell(), SWT.BORDER);
083: end2.setSize(width, width);
084:
085: Rectangle bb;
086: switch (swtSide) {
087: case SWT.TOP:
088: caretControl.setSize(trimRect.width - (2 * hDelta), width);
089: caretControl.setLocation(trimRect.x + hDelta, trimRect.y
090: + trimRect.height + threshold);
091: bb = caretControl.getBounds();
092: end1.setLocation(bb.x, bb.y - width);
093: end2.setLocation((bb.x + bb.width) - width, bb.y - width);
094: break;
095: case SWT.BOTTOM:
096: caretControl.setSize(trimRect.width - (2 * hDelta), width);
097: caretControl.setLocation(trimRect.x + hDelta, trimRect.y
098: - threshold);
099: bb = caretControl.getBounds();
100: end1.setLocation(bb.x, bb.y + width);
101: end2.setLocation((bb.x + bb.width) - width, bb.y + width);
102: break;
103: case SWT.LEFT:
104: caretControl.setSize(width, trimRect.height - (2 * vDelta));
105: caretControl.setLocation(trimRect.x + trimRect.width
106: + threshold, trimRect.y + vDelta);
107: bb = caretControl.getBounds();
108: end1.setLocation(bb.x - bb.width, bb.y);
109: end2.setLocation(bb.x - bb.width, (bb.y + bb.height)
110: - width);
111: break;
112: case SWT.RIGHT:
113: caretControl.setSize(width, trimRect.height - (2 * vDelta));
114: caretControl.setLocation(trimRect.x - threshold, trimRect.y
115: + vDelta);
116: bb = caretControl.getBounds();
117: end1.setLocation(bb.x + bb.width, bb.y);
118: end2.setLocation(bb.x + bb.width, (bb.y + bb.height)
119: - width);
120: break;
121: }
122:
123: // Initially create as not hilighted
124: setHighlight(false);
125: caretControl.moveAbove(null);
126: end1.moveAbove(null);
127: end2.moveAbove(null);
128: }
129:
130: /**
131: * Sets the hilight 'mode' for the control.
132: * @param highlight true if the caret should be drawn as 'hilighted'
133: */
134: public void setHighlight(boolean highlight) {
135: isHighlight = highlight;
136:
137: // if we're displaying as a 'bar' then set the control's background to the
138: // appropriate value
139: if (isHighlight) {
140: caretControl.setBackground(hilightColor);
141: end1.setBackground(hilightColor);
142: end2.setBackground(hilightColor);
143: } else {
144: caretControl.setBackground(baseColor);
145: end1.setBackground(baseColor);
146: end2.setBackground(baseColor);
147: }
148: }
149:
150: public void dispose() {
151: // Dispose the control's resources (we don't have to dispose the
152: // 'bacseColor' because it's a system color
153: hilightColor.dispose();
154:
155: caretControl.dispose();
156: end1.dispose();
157: end2.dispose();
158: }
159: }
|