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.internal.ui.rulers;
|
12
|
|
13
|
import java.util.Iterator;
|
14
|
import java.util.List;
|
15
|
|
16
|
import org.eclipse.draw2d.Figure;
|
17
|
import org.eclipse.draw2d.IFigure;
|
18
|
import org.eclipse.draw2d.geometry.Point;
|
19
|
import org.eclipse.draw2d.geometry.Rectangle;
|
20
|
|
21
|
import org.eclipse.gef.EditPart;
|
22
|
import org.eclipse.gef.GraphicalEditPart;
|
23
|
import org.eclipse.gef.Request;
|
24
|
import org.eclipse.gef.SharedCursors;
|
25
|
import org.eclipse.gef.commands.Command;
|
26
|
import org.eclipse.gef.commands.UnexecutableCommand;
|
27
|
import org.eclipse.gef.editparts.ZoomManager;
|
28
|
import org.eclipse.gef.editpolicies.GraphicalEditPolicy;
|
29
|
import org.eclipse.gef.requests.ChangeBoundsRequest;
|
30
|
|
31
|
/**
|
32
|
* @author Pratik Shah
|
33
|
*/
|
34
|
public class DragGuidePolicy extends GraphicalEditPolicy {
|
35
|
|
36
|
private List attachedEditParts = null;
|
37
|
private IFigure dummyGuideFigure, dummyLineFigure;
|
38
|
private boolean dragInProgress = false;
|
39
|
|
40
|
protected IFigure createDummyLineFigure() {
|
41
|
return new Figure();
|
42
|
}
|
43
|
|
44
|
protected GuideFigure createDummyGuideFigure() {
|
45
|
return new GuidePlaceHolder(getGuideEditPart().isHorizontal());
|
46
|
}
|
47
|
|
48
|
/*
|
49
|
* Fix for Bug# 65885 If you undo guide creation while dragging that guide,
|
50
|
* it was leaving behind drag feedback. This was because by the time
|
51
|
* eraseSourceFeedback() was being called, the guide edit part had been
|
52
|
* deactivated (and hence eraseSourceFeedback is never called on this
|
53
|
* policy). So we make sure that this policy cleans up when it is
|
54
|
* deactivated.
|
55
|
*/
|
56
|
public void deactivate() {
|
57
|
removeFeedback();
|
58
|
super.deactivate();
|
59
|
}
|
60
|
|
61
|
private void eraseAttachedPartsFeedback(Request request) {
|
62
|
if (attachedEditParts != null) {
|
63
|
ChangeBoundsRequest req = new ChangeBoundsRequest(request.getType());
|
64
|
req.setEditParts(attachedEditParts);
|
65
|
|
66
|
Iterator i = attachedEditParts.iterator();
|
67
|
|
68
|
while (i.hasNext())
|
69
|
((EditPart) i.next()).eraseSourceFeedback(req);
|
70
|
attachedEditParts = null;
|
71
|
}
|
72
|
}
|
73
|
|
74
|
public void eraseSourceFeedback(Request request) {
|
75
|
getGuideEditPart().updateLocationOfFigures(
|
76
|
getGuideEditPart().getZoomedPosition());
|
77
|
getHostFigure().setVisible(true);
|
78
|
getGuideEditPart().getGuideLineFigure().setVisible(true);
|
79
|
removeFeedback();
|
80
|
getGuideEditPart().setCurrentCursor(null);
|
81
|
dragInProgress = false;
|
82
|
|
83
|
eraseAttachedPartsFeedback(request);
|
84
|
}
|
85
|
|
86
|
private List getAttachedEditParts() {
|
87
|
if (attachedEditParts == null)
|
88
|
attachedEditParts = getGuideEditPart().getRulerProvider()
|
89
|
.getAttachedEditParts(
|
90
|
getHost().getModel(),
|
91
|
((RulerEditPart) getHost().getParent())
|
92
|
.getDiagramViewer());
|
93
|
return attachedEditParts;
|
94
|
}
|
95
|
|
96
|
public Command getCommand(Request request) {
|
97
|
Command cmd;
|
98
|
final ChangeBoundsRequest req = (ChangeBoundsRequest) request;
|
99
|
if (isDeleteRequest(req)) {
|
100
|
cmd = getGuideEditPart().getRulerProvider().getDeleteGuideCommand(
|
101
|
getHost().getModel());
|
102
|
} else {
|
103
|
int pDelta;
|
104
|
if (getGuideEditPart().isHorizontal()) {
|
105
|
pDelta = req.getMoveDelta().y;
|
106
|
} else {
|
107
|
pDelta = req.getMoveDelta().x;
|
108
|
}
|
109
|
if (isMoveValid(getGuideEditPart().getZoomedPosition() + pDelta)) {
|
110
|
ZoomManager zoomManager = getGuideEditPart().getZoomManager();
|
111
|
if (zoomManager != null) {
|
112
|
pDelta = (int) Math.round(pDelta / zoomManager.getZoom());
|
113
|
}
|
114
|
cmd = getGuideEditPart().getRulerProvider()
|
115
|
.getMoveGuideCommand(getHost().getModel(), pDelta);
|
116
|
} else {
|
117
|
cmd = UnexecutableCommand.INSTANCE;
|
118
|
}
|
119
|
}
|
120
|
return cmd;
|
121
|
}
|
122
|
|
123
|
protected IFigure getDummyGuideFigure() {
|
124
|
if (dummyGuideFigure == null) {
|
125
|
dummyGuideFigure = createDummyGuideFigure();
|
126
|
}
|
127
|
return dummyGuideFigure;
|
128
|
}
|
129
|
|
130
|
protected IFigure getDummyLineFigure() {
|
131
|
if (dummyLineFigure == null) {
|
132
|
dummyLineFigure = createDummyLineFigure();
|
133
|
}
|
134
|
return dummyLineFigure;
|
135
|
}
|
136
|
|
137
|
protected GuideEditPart getGuideEditPart() {
|
138
|
return (GuideEditPart) getHost();
|
139
|
}
|
140
|
|
141
|
protected boolean isDeleteRequest(ChangeBoundsRequest req) {
|
142
|
int pos, max, min;
|
143
|
if (getGuideEditPart().isHorizontal()) {
|
144
|
pos = req.getLocation().x;
|
145
|
Rectangle zone = getHostFigure().getBounds().getExpanded(
|
146
|
GuideEditPart.DELETE_THRESHOLD, 0);
|
147
|
min = zone.x;
|
148
|
max = min + zone.width;
|
149
|
} else {
|
150
|
pos = req.getLocation().y;
|
151
|
Rectangle zone = getHostFigure().getBounds().getExpanded(0,
|
152
|
GuideEditPart.DELETE_THRESHOLD);
|
153
|
min = zone.y;
|
154
|
max = min + zone.height;
|
155
|
}
|
156
|
return pos < min || pos > max;
|
157
|
}
|
158
|
|
159
|
protected boolean isMoveValid(int zoomedPosition) {
|
160
|
boolean result = true;
|
161
|
ZoomManager zoomManager = getGuideEditPart().getZoomManager();
|
162
|
int position = zoomedPosition;
|
163
|
if (zoomManager != null) {
|
164
|
position = (int) Math.round(position / zoomManager.getZoom());
|
165
|
}
|
166
|
Iterator guides = getGuideEditPart().getRulerProvider().getGuides()
|
167
|
.iterator();
|
168
|
while (guides.hasNext()) {
|
169
|
Object guide = guides.next();
|
170
|
if (guide != getGuideEditPart().getModel()) {
|
171
|
int guidePos = getGuideEditPart().getRulerProvider()
|
172
|
.getGuidePosition(guide);
|
173
|
if (Math.abs(guidePos - position) < GuideEditPart.MIN_DISTANCE_BW_GUIDES) {
|
174
|
result = false;
|
175
|
break;
|
176
|
}
|
177
|
}
|
178
|
}
|
179
|
|
180
|
return result;
|
181
|
}
|
182
|
|
183
|
private void removeFeedback() {
|
184
|
if (getDummyGuideFigure().getParent() != null) {
|
185
|
getDummyGuideFigure().getParent().remove(getDummyGuideFigure());
|
186
|
}
|
187
|
if (getDummyLineFigure().getParent() != null) {
|
188
|
getDummyLineFigure().getParent().remove(getDummyLineFigure());
|
189
|
}
|
190
|
}
|
191
|
|
192
|
private void showAttachedPartsFeedback(ChangeBoundsRequest request) {
|
193
|
ChangeBoundsRequest req = new ChangeBoundsRequest(request.getType());
|
194
|
req.setEditParts(getAttachedEditParts());
|
195
|
|
196
|
if (getGuideEditPart().isHorizontal())
|
197
|
req.setMoveDelta(new Point(0, request.getMoveDelta().y));
|
198
|
else
|
199
|
req.setMoveDelta(new Point(request.getMoveDelta().x, 0));
|
200
|
|
201
|
Iterator i = getAttachedEditParts().iterator();
|
202
|
|
203
|
while (i.hasNext())
|
204
|
((EditPart) i.next()).showSourceFeedback(req);
|
205
|
}
|
206
|
|
207
|
public void showSourceFeedback(Request request) {
|
208
|
if (!dragInProgress) {
|
209
|
dragInProgress = true;
|
210
|
// add the placeholder guide figure to the ruler
|
211
|
getHostFigure().getParent().add(getDummyGuideFigure(), 0);
|
212
|
((GraphicalEditPart) getHost().getParent()).setLayoutConstraint(
|
213
|
getHost(), getDummyGuideFigure(), new Integer(
|
214
|
getGuideEditPart().getZoomedPosition()));
|
215
|
getDummyGuideFigure().setBounds(getHostFigure().getBounds());
|
216
|
// add the invisible placeholder line figure to the primary viewer
|
217
|
getGuideEditPart().getGuideLayer().add(getDummyLineFigure(), 0);
|
218
|
getGuideEditPart().getGuideLayer().setConstraint(
|
219
|
getDummyLineFigure(),
|
220
|
new Boolean(getGuideEditPart().isHorizontal()));
|
221
|
getDummyLineFigure().setBounds(
|
222
|
getGuideEditPart().getGuideLineFigure().getBounds());
|
223
|
// move the guide being dragged to the last index so that it's drawn
|
224
|
// on
|
225
|
// top of other guides
|
226
|
List children = getHostFigure().getParent().getChildren();
|
227
|
children.remove(getHostFigure());
|
228
|
children.add(getHostFigure());
|
229
|
}
|
230
|
ChangeBoundsRequest req = (ChangeBoundsRequest) request;
|
231
|
if (isDeleteRequest(req)) {
|
232
|
getHostFigure().setVisible(false);
|
233
|
getGuideEditPart().getGuideLineFigure().setVisible(false);
|
234
|
getGuideEditPart().setCurrentCursor(SharedCursors.ARROW);
|
235
|
eraseAttachedPartsFeedback(request);
|
236
|
} else {
|
237
|
int newPosition;
|
238
|
if (getGuideEditPart().isHorizontal()) {
|
239
|
newPosition = getGuideEditPart().getZoomedPosition()
|
240
|
+ req.getMoveDelta().y;
|
241
|
} else {
|
242
|
newPosition = getGuideEditPart().getZoomedPosition()
|
243
|
+ req.getMoveDelta().x;
|
244
|
}
|
245
|
getHostFigure().setVisible(true);
|
246
|
getGuideEditPart().getGuideLineFigure().setVisible(true);
|
247
|
if (isMoveValid(newPosition)) {
|
248
|
getGuideEditPart().setCurrentCursor(null);
|
249
|
getGuideEditPart().updateLocationOfFigures(newPosition);
|
250
|
showAttachedPartsFeedback(req);
|
251
|
} else {
|
252
|
getGuideEditPart().setCurrentCursor(SharedCursors.NO);
|
253
|
getGuideEditPart().updateLocationOfFigures(
|
254
|
getGuideEditPart().getZoomedPosition());
|
255
|
eraseAttachedPartsFeedback(request);
|
256
|
}
|
257
|
}
|
258
|
}
|
259
|
|
260
|
public boolean understandsRequest(Request req) {
|
261
|
return req.getType().equals(REQ_MOVE);
|
262
|
}
|
263
|
|
264
|
}
|