1
|
/*******************************************************************************
|
2
|
* Copyright (c) 2003, 2010 IBM Corporation and others.
|
3
|
* All rights reserved. This program and the accompanying materials
|
4
|
* are made available under the terms of the Eclipse Public License v1.0
|
5
|
* which accompanies this distribution, and is available at
|
6
|
* http://www.eclipse.org/legal/epl-v10.html
|
7
|
*
|
8
|
* Contributors:
|
9
|
* IBM Corporation - initial API and implementation
|
10
|
*******************************************************************************/
|
11
|
package org.eclipse.gef.editpolicies;
|
12
|
|
13
|
import org.eclipse.swt.graphics.Color;
|
14
|
import org.eclipse.swt.graphics.Image;
|
15
|
import org.eclipse.swt.graphics.ImageData;
|
16
|
import org.eclipse.swt.graphics.PaletteData;
|
17
|
import org.eclipse.swt.widgets.Display;
|
18
|
|
19
|
import org.eclipse.draw2d.ColorConstants;
|
20
|
import org.eclipse.draw2d.Figure;
|
21
|
import org.eclipse.draw2d.FigureUtilities;
|
22
|
import org.eclipse.draw2d.Graphics;
|
23
|
import org.eclipse.draw2d.IFigure;
|
24
|
import org.eclipse.draw2d.geometry.PrecisionPoint;
|
25
|
import org.eclipse.draw2d.geometry.Rectangle;
|
26
|
|
27
|
import org.eclipse.gef.GraphicalEditPart;
|
28
|
import org.eclipse.gef.Request;
|
29
|
import org.eclipse.gef.SnapToGeometry;
|
30
|
import org.eclipse.gef.SnapToGuides;
|
31
|
|
32
|
/**
|
33
|
* An EditPolicy that is used to show snap feedback for guides (red lines) and
|
34
|
* geometry (blue lines). This policy is not required for Grids.
|
35
|
*
|
36
|
* @author Randy Hudson
|
37
|
* @author Pratik Shah
|
38
|
* @since 3.0
|
39
|
*/
|
40
|
public class SnapFeedbackPolicy extends GraphicalEditPolicy {
|
41
|
|
42
|
IFigure guide[] = new IFigure[6];
|
43
|
Integer location[] = new Integer[6];
|
44
|
|
45
|
/**
|
46
|
* @see org.eclipse.gef.EditPolicy#eraseTargetFeedback(org.eclipse.gef.Request)
|
47
|
*/
|
48
|
public void eraseTargetFeedback(Request request) {
|
49
|
for (int i = 0; i < guide.length; i++) {
|
50
|
if (guide[i] != null)
|
51
|
removeFeedback(guide[i]);
|
52
|
guide[i] = null;
|
53
|
location[i] = null;
|
54
|
}
|
55
|
}
|
56
|
|
57
|
static class FadeIn extends Figure {
|
58
|
int opacity = 0;
|
59
|
static final int FRAMES = 6;
|
60
|
Image image;
|
61
|
static int count;
|
62
|
|
63
|
FadeIn(Color bg) {
|
64
|
setBackgroundColor(bg);
|
65
|
super.setOpaque(true);
|
66
|
}
|
67
|
|
68
|
private Color createMixedColor() {
|
69
|
return FigureUtilities
|
70
|
.mixColors(getLocalBackgroundColor(), getParent()
|
71
|
.getBackgroundColor(), (double) opacity / FRAMES);
|
72
|
}
|
73
|
|
74
|
/**
|
75
|
* @see org.eclipse.draw2d.Figure#paintFigure(org.eclipse.draw2d.Graphics)
|
76
|
*/
|
77
|
protected void paintFigure(Graphics graphics) {
|
78
|
if (opacity != FRAMES) {
|
79
|
if (image != null) {
|
80
|
image.dispose();
|
81
|
count--;
|
82
|
image = null;
|
83
|
}
|
84
|
if (opacity != FRAMES - 1) {
|
85
|
Display display = Display.getCurrent();
|
86
|
PaletteData pData = new PaletteData(0xFF, 0xFF00, 0xFF0000);
|
87
|
Color localBackgroundColor = createMixedColor();
|
88
|
int fillColor = pData.getPixel(localBackgroundColor
|
89
|
.getRGB());
|
90
|
localBackgroundColor.dispose();
|
91
|
ImageData iData = new ImageData(1, 1, 24, pData);
|
92
|
iData.setPixel(0, 0, fillColor);
|
93
|
iData.setAlpha(0, 0, 255 * opacity / FRAMES);
|
94
|
image = new Image(display, iData);
|
95
|
count++;
|
96
|
}
|
97
|
Display.getCurrent().timerExec(100, new Runnable() {
|
98
|
public void run() {
|
99
|
opacity = Math.min(FRAMES, opacity + 1);
|
100
|
repaint();
|
101
|
}
|
102
|
});
|
103
|
}
|
104
|
Rectangle r = getBounds();
|
105
|
if (image != null)
|
106
|
graphics.drawImage(image, 0, 0, 1, 1, r.x, r.y, r.width,
|
107
|
r.height);
|
108
|
else
|
109
|
super.paintFigure(graphics);
|
110
|
}
|
111
|
|
112
|
/**
|
113
|
* @see org.eclipse.draw2d.Figure#removeNotify()
|
114
|
*/
|
115
|
public void removeNotify() {
|
116
|
if (image != null) {
|
117
|
image.dispose();
|
118
|
count--;
|
119
|
image = null;
|
120
|
}
|
121
|
}
|
122
|
}
|
123
|
|
124
|
// Even offset indicates a vertical feedback line; odd, horizontal.
|
125
|
void highlightGuide(Integer pos, Color color, int offset) {
|
126
|
if (pos == null) {
|
127
|
if (guide[offset] != null) {
|
128
|
removeFeedback(guide[offset]);
|
129
|
guide[offset] = null;
|
130
|
}
|
131
|
location[offset] = pos;
|
132
|
return;
|
133
|
}
|
134
|
|
135
|
// pos is an integer relative to target's client area.
|
136
|
// translate pos to absolute, and then make it relative to fig.
|
137
|
int position = pos.intValue();
|
138
|
PrecisionPoint loc = new PrecisionPoint(position, position);
|
139
|
IFigure contentPane = ((GraphicalEditPart) getHost()).getContentPane();
|
140
|
contentPane.translateToParent(loc);
|
141
|
contentPane.translateToAbsolute(loc);
|
142
|
|
143
|
if (location[offset] == null || !location[offset].equals(pos)) {
|
144
|
location[offset] = pos;
|
145
|
if (guide[offset] != null) {
|
146
|
removeFeedback(guide[offset]);
|
147
|
guide[offset] = null;
|
148
|
}
|
149
|
|
150
|
IFigure fig = new FadeIn(color);
|
151
|
guide[offset] = fig;
|
152
|
addFeedback(fig);
|
153
|
fig.translateToRelative(loc);
|
154
|
position = offset % 2 == 0 ? (int) Math.round(loc.preciseX())
|
155
|
: (int) Math.round(loc.preciseY());
|
156
|
Rectangle figBounds = getFeedbackLayer().getBounds().getCopy();
|
157
|
if ((offset % 2) == 1) {
|
158
|
figBounds.height = 1;
|
159
|
figBounds.y = position;
|
160
|
} else {
|
161
|
figBounds.x = position;
|
162
|
figBounds.width = 1;
|
163
|
}
|
164
|
fig.setBounds(figBounds);
|
165
|
} else {
|
166
|
// The feedback layer could have grown (if auto-scrolling), so
|
167
|
// resize the fade-in
|
168
|
// line.
|
169
|
IFigure fig = guide[offset];
|
170
|
Rectangle figBounds = fig.getBounds().getCopy();
|
171
|
Rectangle feedbackBounds = getFeedbackLayer().getBounds();
|
172
|
if ((offset % 2) == 1) {
|
173
|
figBounds.x = feedbackBounds.x;
|
174
|
figBounds.width = feedbackBounds.width;
|
175
|
} else {
|
176
|
figBounds.y = feedbackBounds.y;
|
177
|
figBounds.height = feedbackBounds.height;
|
178
|
}
|
179
|
fig.setBounds(figBounds);
|
180
|
}
|
181
|
}
|
182
|
|
183
|
/**
|
184
|
* @see org.eclipse.gef.EditPolicy#showTargetFeedback(org.eclipse.gef.Request)
|
185
|
*/
|
186
|
public void showTargetFeedback(Request req) {
|
187
|
if (req.getType().equals(REQ_MOVE) || req.getType().equals(REQ_RESIZE)
|
188
|
|| req.getType().equals(REQ_CLONE)
|
189
|
|| req.getType().equals(REQ_ADD)
|
190
|
|| req.getType().equals(REQ_CREATE)) {
|
191
|
|
192
|
Integer value;
|
193
|
value = (Integer) req.getExtendedData().get(
|
194
|
SnapToGeometry.KEY_WEST_ANCHOR);
|
195
|
highlightGuide(value, ColorConstants.blue, 0);
|
196
|
|
197
|
value = (Integer) req.getExtendedData().get(
|
198
|
SnapToGeometry.KEY_NORTH_ANCHOR);
|
199
|
highlightGuide(value, ColorConstants.blue, 1);
|
200
|
|
201
|
value = (Integer) req.getExtendedData().get(
|
202
|
SnapToGeometry.KEY_EAST_ANCHOR);
|
203
|
highlightGuide(value, ColorConstants.blue, 2);
|
204
|
|
205
|
value = (Integer) req.getExtendedData().get(
|
206
|
SnapToGeometry.KEY_SOUTH_ANCHOR);
|
207
|
highlightGuide(value, ColorConstants.blue, 3);
|
208
|
|
209
|
value = (Integer) req.getExtendedData().get(
|
210
|
SnapToGuides.KEY_VERTICAL_GUIDE);
|
211
|
highlightGuide(value, ColorConstants.red, 4);
|
212
|
|
213
|
value = (Integer) req.getExtendedData().get(
|
214
|
SnapToGuides.KEY_HORIZONTAL_GUIDE);
|
215
|
highlightGuide(value, ColorConstants.red, 5);
|
216
|
}
|
217
|
}
|
218
|
|
219
|
}
|