Project

General

Profile

Download (10.4 KB) Statistics
| Branch: | Tag: | Revision:
1
/*******************************************************************************
2
 * Copyright (c) 2000, 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.editparts;
12

    
13
import java.beans.PropertyChangeEvent;
14
import java.beans.PropertyChangeListener;
15

    
16
import org.eclipse.draw2d.ConnectionLayer;
17
import org.eclipse.draw2d.IFigure;
18
import org.eclipse.draw2d.Layer;
19
import org.eclipse.draw2d.LayeredPane;
20
import org.eclipse.draw2d.ScalableLayeredPane;
21
import org.eclipse.draw2d.StackLayout;
22
import org.eclipse.draw2d.Viewport;
23
import org.eclipse.draw2d.geometry.Dimension;
24
import org.eclipse.draw2d.geometry.Point;
25
import org.eclipse.draw2d.geometry.Rectangle;
26

    
27
import org.eclipse.gef.AutoexposeHelper;
28
import org.eclipse.gef.DragTracker;
29
import org.eclipse.gef.LayerConstants;
30
import org.eclipse.gef.Request;
31
import org.eclipse.gef.SnapToGrid;
32
import org.eclipse.gef.tools.MarqueeDragTracker;
33

    
34
/**
35
 * A graphical root composed of regular {@link org.eclipse.draw2d.Layer Layers}.
36
 * The layers are added to {@link org.eclipse.draw2d.LayeredPane} or
37
 * {@link org.eclipse.draw2d.ScalableLayeredPane}. All layers are positioned by
38
 * {@link org.eclipse.draw2d.StackLayout}s, which means that the diagrams
39
 * preferred size is the union of the preferred size of each layer, and all
40
 * layers will be positioned to fill the entire diagram.
41
 * <P>
42
 * <EM>IMPORTANT</EM>ScalableRootEditPart uses a <code>Viewport</code> as its
43
 * primary figure. It must be used with a
44
 * {@link org.eclipse.gef.ui.parts.ScrollingGraphicalViewer}. The viewport gets
45
 * installed into that viewer's {@link org.eclipse.draw2d.FigureCanvas}, which
46
 * provides native scrollbars for scrolling the viewport.
47
 * <P>
48
 * The layer structure (top-to-bottom) for this root is:
49
 * <table cellspacing="0" cellpadding="0">
50
 * <tr>
51
 * <td colspan="4">Root Layered Pane</td>
52
 * </tr>
53
 * <tr>
54
 * <td>&#9500;</td>
55
 * <td colspan="3">&nbsp;Guide Layer</td>
56
 * </tr>
57
 * <tr>
58
 * <td>&#9500;</td>
59
 * <td colspan="3">&nbsp;Feedback Layer</td>
60
 * </tr>
61
 * <tr>
62
 * <td>&#9500;</td>
63
 * <td colspan="3">&nbsp;Handle Layer</td>
64
 * </tr>
65
 * <tr>
66
 * <td>&#9492;</td>
67
 * <td colspan="2">&nbsp;<b>Scalable Layers</b></td>
68
 * <td>({@link ScalableLayeredPane})</td>
69
 * </tr>
70
 * <tr>
71
 * <td>&nbsp;</td>
72
 * <td>&#9500;</td>
73
 * <td colspan="2">&nbsp;Scaled Feedback Layer</td>
74
 * </tr>
75
 * <tr>
76
 * <td>&nbsp;</td>
77
 * <td>&#9500;</td>
78
 * <td colspan="2">&nbsp;Printable Layers</td>
79
 * </tr>
80
 * <tr>
81
 * <td>&nbsp;</td>
82
 * <td>&nbsp;</td>
83
 * <td>&#9500; Connection Layer</td>
84
 * </tr>
85
 * <tr>
86
 * <td>&nbsp;</td>
87
 * <td>&nbsp;</td>
88
 * <td>&#9492;&nbsp;Primary Layer</td>
89
 * <td>&nbsp;</td>
90
 * </tr>
91
 * <tr>
92
 * <td>&nbsp;</td>
93
 * <td>&#9492;</td>
94
 * <td colspan="2">&nbsp;Grid Layer</td>
95
 * </tr>
96
 * </table>
97
 * 
98
 * @author Eric Bordeau
99
 * @since 2.1.1
100
 */
101
public class ScalableRootEditPart extends SimpleRootEditPart implements
102
		LayerConstants, LayerManager {
103

    
104
	class FeedbackLayer extends Layer {
105
		FeedbackLayer() {
106
			setEnabled(false);
107
		}
108

    
109
		/**
110
		 * @see org.eclipse.draw2d.Figure#getPreferredSize(int, int)
111
		 */
112
		public Dimension getPreferredSize(int wHint, int hHint) {
113
			Rectangle rect = new Rectangle();
114
			for (int i = 0; i < getChildren().size(); i++)
115
				rect.union(((IFigure) getChildren().get(i)).getBounds());
116
			return rect.getSize();
117
		}
118

    
119
	}
120

    
121
	private LayeredPane innerLayers;
122
	private LayeredPane printableLayers;
123
	private ScalableLayeredPane scaledLayers;
124
	private PropertyChangeListener gridListener = new PropertyChangeListener() {
125
		public void propertyChange(PropertyChangeEvent evt) {
126
			String property = evt.getPropertyName();
127
			if (property.equals(SnapToGrid.PROPERTY_GRID_ORIGIN)
128
					|| property.equals(SnapToGrid.PROPERTY_GRID_SPACING)
129
					|| property.equals(SnapToGrid.PROPERTY_GRID_VISIBLE))
130
				refreshGridLayer();
131
		}
132
	};
133

    
134
	private ZoomManager zoomManager;
135

    
136
	/**
137
	 * Constructor for ScalableFreeformRootEditPart
138
	 */
139
	public ScalableRootEditPart() {
140
		zoomManager = new ZoomManager((ScalableLayeredPane) getScaledLayers(),
141
				((Viewport) getFigure()));
142
	}
143

    
144
	/**
145
	 * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#createFigure()
146
	 */
147
	protected IFigure createFigure() {
148
		Viewport viewport = createViewport();
149

    
150
		innerLayers = new LayeredPane();
151
		createLayers(innerLayers);
152

    
153
		viewport.setContents(innerLayers);
154
		return viewport;
155
	}
156

    
157
	/**
158
	 * Creates a {@link GridLayer grid}. Sub-classes can override this method to
159
	 * customize the appearance of the grid. The grid layer should be the first
160
	 * layer (i.e., beneath the primary layer) if it is not to cover up parts on
161
	 * the primary layer. In that case, the primary layer should be transparent
162
	 * so that the grid is visible.
163
	 * 
164
	 * @return the newly created GridLayer
165
	 */
166
	protected GridLayer createGridLayer() {
167
		return new GridLayer();
168
	}
169

    
170
	/**
171
	 * Creates the top-most set of layers on the given layered pane
172
	 * 
173
	 * @param layeredPane
174
	 *            the parent for the created layers
175
	 */
176
	protected void createLayers(LayeredPane layeredPane) {
177
		layeredPane.add(getScaledLayers(), SCALABLE_LAYERS);
178
		layeredPane.add(new Layer() {
179
			public Dimension getPreferredSize(int wHint, int hHint) {
180
				return new Dimension();
181
			}
182
		}, HANDLE_LAYER);
183
		layeredPane.add(new FeedbackLayer(), FEEDBACK_LAYER);
184
		layeredPane.add(new GuideLayer(), GUIDE_LAYER);
185
	}
186

    
187
	/**
188
	 * Creates a layered pane and the layers that should be printed.
189
	 * 
190
	 * @see org.eclipse.gef.print.PrintGraphicalViewerOperation
191
	 * @return a new LayeredPane containing the printable layers
192
	 */
193
	protected LayeredPane createPrintableLayers() {
194
		LayeredPane pane = new LayeredPane();
195

    
196
		Layer layer = new Layer();
197
		layer.setLayoutManager(new StackLayout());
198
		pane.add(layer, PRIMARY_LAYER);
199

    
200
		layer = new ConnectionLayer();
201
		layer.setPreferredSize(new Dimension(5, 5));
202
		pane.add(layer, CONNECTION_LAYER);
203

    
204
		return pane;
205
	}
206

    
207
	/**
208
	 * Creates a scalable layered pane and the layers that should be scaled.
209
	 * 
210
	 * @return a new <code>ScalableLayeredPane</code> containing the scalable
211
	 *         layers
212
	 */
213
	protected ScalableLayeredPane createScaledLayers() {
214
		ScalableLayeredPane layers = new ScalableLayeredPane();
215
		layers.add(createGridLayer(), GRID_LAYER);
216
		layers.add(getPrintableLayers(), PRINTABLE_LAYERS);
217
		layers.add(new FeedbackLayer(), SCALED_FEEDBACK_LAYER);
218
		return layers;
219
	}
220

    
221
	/**
222
	 * Constructs the viewport that will be used to contain all of the layers.
223
	 * 
224
	 * @return a new Viewport
225
	 */
226
	protected Viewport createViewport() {
227
		return new Viewport(true);
228
	}
229

    
230
	/**
231
	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
232
	 */
233
	public Object getAdapter(Class key) {
234
		if (key == AutoexposeHelper.class)
235
			return new ViewportAutoexposeHelper(this);
236
		return super.getAdapter(key);
237
	}
238

    
239
	/**
240
	 * The contents' Figure will be added to the PRIMARY_LAYER.
241
	 * 
242
	 * @see org.eclipse.gef.GraphicalEditPart#getContentPane()
243
	 */
244
	public IFigure getContentPane() {
245
		return getLayer(PRIMARY_LAYER);
246
	}
247

    
248
	/**
249
	 * Should not be called, but returns a MarqeeDragTracker for good measure.
250
	 * 
251
	 * @see org.eclipse.gef.EditPart#getDragTracker(org.eclipse.gef.Request)
252
	 */
253
	public DragTracker getDragTracker(Request req) {
254
		/*
255
		 * The root will only be asked for a drag tracker if for some reason the
256
		 * contents editpart says it is neither selector nor opaque.
257
		 */
258
		return new MarqueeDragTracker();
259
	}
260

    
261
	/**
262
	 * Returns the layer indicated by the key. Searches all layered panes.
263
	 * 
264
	 * @see LayerManager#getLayer(Object)
265
	 */
266
	public IFigure getLayer(Object key) {
267
		if (innerLayers == null)
268
			return null;
269
		IFigure layer = scaledLayers.getLayer(key);
270
		if (layer != null)
271
			return layer;
272
		layer = printableLayers.getLayer(key);
273
		if (layer != null)
274
			return layer;
275
		return innerLayers.getLayer(key);
276
	}
277

    
278
	/**
279
	 * The root editpart does not have a real model. The LayerManager ID is
280
	 * returned so that this editpart gets registered using that key.
281
	 * 
282
	 * @see org.eclipse.gef.EditPart#getModel()
283
	 */
284
	public Object getModel() {
285
		return LayerManager.ID;
286
	}
287

    
288
	/**
289
	 * Returns the LayeredPane that should be used during printing. This layer
290
	 * will be identified using {@link LayerConstants#PRINTABLE_LAYERS}.
291
	 * 
292
	 * @return the layered pane containing all printable content
293
	 */
294
	protected LayeredPane getPrintableLayers() {
295
		if (printableLayers == null)
296
			printableLayers = createPrintableLayers();
297
		return printableLayers;
298
	}
299

    
300
	/**
301
	 * Returns the scalable layers of this EditPart
302
	 * 
303
	 * @return LayeredPane
304
	 */
305
	protected LayeredPane getScaledLayers() {
306
		if (scaledLayers == null)
307
			scaledLayers = createScaledLayers();
308
		return scaledLayers;
309
	}
310

    
311
	/**
312
	 * Returns the zoomManager.
313
	 * 
314
	 * @return ZoomManager
315
	 */
316
	public ZoomManager getZoomManager() {
317
		return zoomManager;
318
	}
319

    
320
	/**
321
	 * Updates the {@link GridLayer grid} based on properties set on the
322
	 * {@link #getViewer() graphical viewer}:
323
	 * {@link SnapToGrid#PROPERTY_GRID_VISIBLE},
324
	 * {@link SnapToGrid#PROPERTY_GRID_SPACING}, and
325
	 * {@link SnapToGrid#PROPERTY_GRID_ORIGIN}.
326
	 * <p>
327
	 * This method is invoked initially when the GridLayer is created, and when
328
	 * any of the above-mentioned properties are changed on the viewer.
329
	 */
330
	protected void refreshGridLayer() {
331
		boolean visible = false;
332
		GridLayer grid = (GridLayer) getLayer(GRID_LAYER);
333
		Boolean val = (Boolean) getViewer().getProperty(
334
				SnapToGrid.PROPERTY_GRID_VISIBLE);
335
		if (val != null)
336
			visible = val.booleanValue();
337
		grid.setOrigin((Point) getViewer().getProperty(
338
				SnapToGrid.PROPERTY_GRID_ORIGIN));
339
		grid.setSpacing((Dimension) getViewer().getProperty(
340
				SnapToGrid.PROPERTY_GRID_SPACING));
341
		grid.setVisible(visible);
342
	}
343

    
344
	/**
345
	 * @see org.eclipse.gef.editparts.AbstractEditPart#register()
346
	 */
347
	protected void register() {
348
		super.register();
349
		getViewer().setProperty(ZoomManager.class.toString(), getZoomManager());
350
		if (getLayer(GRID_LAYER) != null) {
351
			getViewer().addPropertyChangeListener(gridListener);
352
			refreshGridLayer();
353
		}
354
	}
355

    
356
	/**
357
	 * @see org.eclipse.gef.editparts.AbstractEditPart#unregister()
358
	 */
359
	protected void unregister() {
360
		getViewer().removePropertyChangeListener(gridListener);
361
		super.unregister();
362
		getViewer().setProperty(ZoomManager.class.toString(), null);
363
	}
364

    
365
}
(13-13/21)