001: /*
002: * uDig - User Friendly Desktop Internet GIS client http://udig.refractions.net (C) 2004,
003: * Refractions Research Inc. This library is free software; you can redistribute it and/or modify it
004: * under the terms of the GNU Lesser General Public License as published by the Free Software
005: * Foundation; version 2.1 of the License. This library is distributed in the hope that it will be
006: * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
007: * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
008: */
009: package net.refractions.udig.project.ui.internal.render.displayAdapter.impl;
010:
011: import java.awt.Canvas;
012: import java.awt.Color;
013: import java.awt.Dimension;
014: import java.awt.Graphics;
015: import java.awt.Graphics2D;
016: import java.awt.geom.AffineTransform;
017: import java.awt.image.BufferedImage;
018: import java.awt.image.RenderedImage;
019: import java.awt.image.VolatileImage;
020:
021: import net.refractions.udig.project.internal.render.RenderExecutor;
022: import net.refractions.udig.project.internal.render.RenderManager;
023: import net.refractions.udig.project.internal.render.Renderer;
024: import net.refractions.udig.project.render.IRenderContext;
025: import net.refractions.udig.project.render.IRenderer;
026: import net.refractions.udig.project.render.displayAdapter.IMapDisplayListener;
027: import net.refractions.udig.project.ui.commands.IDrawCommand;
028: import net.refractions.udig.project.ui.internal.MapEditor;
029: import net.refractions.udig.project.ui.internal.ProjectUIPlugin;
030: import net.refractions.udig.project.ui.render.displayAdapter.MapMouseListener;
031: import net.refractions.udig.project.ui.render.displayAdapter.MapMouseMotionListener;
032: import net.refractions.udig.project.ui.render.displayAdapter.MapMouseWheelListener;
033: import net.refractions.udig.project.ui.render.displayAdapter.ViewportPane;
034: import net.refractions.udig.ui.graphics.AWTGraphics;
035: import net.refractions.udig.ui.graphics.ViewportGraphics;
036:
037: import org.eclipse.core.runtime.Platform;
038: import org.eclipse.gef.editparts.GridLayer;
039: import org.eclipse.swt.SWT;
040: import org.eclipse.swt.awt.SWT_AWT;
041: import org.eclipse.swt.graphics.Cursor;
042: import org.eclipse.swt.layout.GridData;
043: import org.eclipse.swt.layout.GridLayout;
044: import org.eclipse.swt.widgets.Composite;
045: import org.eclipse.swt.widgets.Control;
046: import org.eclipse.swt.widgets.Display;
047: import org.eclipse.swt.widgets.Event;
048:
049: /**
050: * The ViewportPaneImpl is a java.awt.Panel that is the display area for a Map. It Registers itself
051: * with a CompositeRenderer and obtains the image from the CompositeRenderer if the
052: * CompositeRenderer is "ready"
053: *
054: * @author Jesse Eichar
055: * @version $Revision: 1.9 $
056: * @deprecated
057: */
058: public class ViewportPaneJava extends Canvas implements ViewportPane {
059: ViewportPainter painter = new ViewportPainter(this );
060: private static final long serialVersionUID = 1L;
061: private static final int DEFAULT_DPI = 72;
062: ViewportPane pane = this ;
063: private final static AffineTransform IDENTITY = new AffineTransform();
064: private VolatileImage vImage;
065: VolatileImage buffer;
066: private Composite composite = null;
067: EventJob eventJob = new EventJob();
068: private RenderManager renderManager;
069: private EventHandler handler;
070: private MapEditor editor;
071:
072: /**
073: * Create a image that is compatable with this ViewportPane.
074: * <p>
075: * This image is expected to be a "Managed Image" and thus hardware accelarated.
076: * </p>
077: *
078: * @see ViewportPane#image(int, int)
079: * @param w width
080: * @param h height
081: * @return BufferedImage directly backed by AWT
082: */
083: public BufferedImage image(int w, int h) {
084: return (BufferedImage) createImage(w, h);
085: }
086:
087: /**
088: * Creates a new ViewportPaneImpl object.
089: *
090: * @param comp The Composite that this pane will be embedded into
091: * @param editor editor that contains this viewport
092: */
093: public ViewportPaneJava(Composite parent, MapEditor editor) {
094: this .editor = editor;
095: handler = new EventHandler(this , eventJob);
096: // setBackground(Color.WHITE);
097:
098: Composite comp = new Composite(parent, SWT.NONE);
099: comp.addListener(SWT.MouseDoubleClick, handler);
100: comp.addListener(SWT.MouseDown, handler);
101: comp.addListener(SWT.MouseEnter, handler);
102: comp.addListener(SWT.MouseExit, handler);
103: comp.addListener(SWT.MouseHover, handler);
104: comp.addListener(SWT.MouseMove, handler);
105: comp.addListener(SWT.MouseUp, handler);
106: comp.addListener(SWT.MouseWheel, handler);
107: comp.addListener(SWT.Resize, handler);
108: comp.addListener(SWT.KeyDown, handler);
109:
110: comp.setLayout(new GridLayout());
111:
112: Composite child = new Composite(comp, SWT.EMBEDDED
113: | SWT.NO_BACKGROUND);
114: GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
115: child.setLayoutData(gridData);
116: child.setEnabled(false);
117: SWT_AWT.new_Frame(child).add(this );
118: composite = comp;
119: setBackgroundColor();
120: }
121:
122: private void setBackgroundColor() {
123: composite.setBackground(Display.getDefault().getSystemColor(
124: SWT.COLOR_WHITE));
125: setBackground(Color.WHITE);
126: }
127:
128: /**
129: * @see net.refractions.udig.project.ui.render.displayAdapter.ViewportPane#setRenderManager(net.refractions.udig.project.render.RenderManager)
130: */
131: public void setRenderManager(RenderManager manager) {
132: this .renderManager = manager;
133: }
134:
135: /**
136: * @see java.awt.Canvas#paint(java.awt.Graphics)
137: */
138: public void paint(Graphics g) {
139: initializeViewportModel();
140: if (vImage == null) {
141: clearDisplay(g);
142: return;
143: }
144:
145: initializeBuffer();
146: do {
147: drawOnOffScreenBuffer();
148:
149: drawOnScreen(g);
150: } while (buffer.contentsLost());
151: }
152:
153: private void drawOnScreen(Graphics g) {
154: int minWidth = Math.min(buffer.getWidth(),
155: g.getClipBounds().width);
156: int minHeight = Math.min(buffer.getHeight(),
157: g.getClipBounds().height);
158: g.drawImage(buffer, 0, 0, minWidth, minHeight, 0, 0, minWidth,
159: minHeight, this );
160: }
161:
162: private void drawOnOffScreenBuffer() {
163:
164: Graphics2D graphics = buffer.createGraphics();
165: // graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
166: ViewportGraphics vg = new AWTGraphics(graphics);
167: do {
168: int minWidth = Math.min(buffer.getWidth(), getWidth());
169: int minHeight = Math.min(buffer.getHeight(), getHeight());
170: validateVolitileImage();
171: painter.paint(vg, vImage, minWidth, minHeight);
172: } while (vImage.contentsLost());
173: }
174:
175: private void validateVolitileImage() {
176: int returnCode;
177: returnCode = vImage.validate(getGraphicsConfiguration());
178: if (returnCode == VolatileImage.IMAGE_RESTORED) {
179: // Contents need to be restored
180: copyImageToVolitileImage(false); // restore contents
181: } else if (returnCode == VolatileImage.IMAGE_INCOMPATIBLE) {
182: // old vImg doesn't work with new GraphicsConfig; re-create
183: // it
184: vImage = createVolatileImage(getWidth(), getHeight());
185: copyImageToVolitileImage(false);
186: }
187: }
188:
189: private void initializeBuffer() {
190: if (buffer == null || buffer.getWidth() < getWidth()
191: || buffer.getHeight() < getHeight())
192: buffer = createVolatileImage(getWidth(), getHeight());
193: }
194:
195: private void clearDisplay(Graphics g) {
196: Graphics2D graphics = (Graphics2D) g;
197: graphics.clearRect(0, 0, getWidth(), getHeight());
198: return;
199: }
200:
201: private void initializeViewportModel() {
202: if (renderManager != null
203: && !renderManager.getViewportModelInternal()
204: .isInitialized()) {
205: Event event = new Event();
206: event.display = Display.getDefault();
207: // eventJob.fire( EventJob.RESIZED, new MapDisplayEvent(this, new Dimension(0,0),
208: // getSize()) );
209: handler.controlResized(event);
210: }
211:
212: }
213:
214: void copyImageToVolitileImage(boolean clearImage) {
215: if (vImage == null)
216: return;
217: do {
218: if (vImage.validate(getGraphicsConfiguration()) == VolatileImage.IMAGE_INCOMPATIBLE) {
219: // old vImg doesn't work with new GraphicsConfig; re-create it
220: vImage = createVolatileImage(getWidth(), getHeight());
221: }
222: Graphics2D graphics = vImage.createGraphics();
223: if (clearImage)
224: graphics.clearRect(0, 0, vImage.getWidth(), vImage
225: .getHeight());
226: graphics.drawRenderedImage(getImage(), IDENTITY);
227: graphics.dispose();
228: } while (vImage.contentsLost());
229: }
230:
231: private void initMap() {
232: if (getImage() == null) {
233: return;
234: }
235: if (vImage == null || vImage.getWidth() < getWidth()
236: || vImage.getHeight() < getHeight()) {
237: vImage = createVolatileImage(getWidth(), getHeight());
238: }
239: copyImageToVolitileImage(true);
240: }
241:
242: RenderedImage getImage() {
243: if (!Platform.isRunning())
244: return null;
245: try {
246: RenderExecutor renderExecutor = renderManager
247: .getRenderExecutor();
248: Renderer renderer = renderExecutor.getRenderer();
249: if (renderer.getState() == IRenderer.DISPOSED)
250: return null;
251: IRenderContext context = renderer.getContext();
252: return context.getImage();
253: } catch (Throwable e) {
254: ProjectUIPlugin.log(null, e);
255: return null;
256: }
257: }
258:
259: /**
260: * @see java.awt.Component#update(java.awt.Graphics)
261: */
262: public void update(Graphics g) {
263: paint(g);
264: }
265:
266: /**
267: * @see ViewportPane#dispose()
268: */
269: public void dispose() {
270: composite.dispose();
271: }
272:
273: /**
274: * @see ViewportPane#addDrawCommand(IDrawCommand)
275: */
276: public void addDrawCommand(IDrawCommand command) {
277: painter.addDrawCommand(command);
278: }
279:
280: /**
281: * @see net.refractions.udig.project.render.displayAdapter.IMapDisplay#getDisplaySize()
282: * @return the size of the viewportpane
283: */
284: public Dimension getDisplaySize() {
285: return getSize();
286: }
287:
288: /**
289: * @see ViewportPane#removeMouseListener(MapMouseListener)
290: */
291: public void removeMouseListener(MapMouseListener l) {
292: eventJob.removeMouseListener(l);
293: }
294:
295: /**
296: * @see ViewportPane#removeMouseMotionListener(MapMouseMotionListener)
297: */
298: public void removeMouseMotionListener(MapMouseMotionListener l) {
299: eventJob.removeMouseMotionListener(l);
300: }
301:
302: /**
303: * @see ViewportPane#removeMouseWheelListener(MapMouseWheelListener)
304: */
305: public void removeMouseWheelListener(MapMouseWheelListener l) {
306: eventJob.removeMouseWheelListener(l);
307: }
308:
309: /**
310: * @see ViewportPane#addMouseListener(MapMouseListener)
311: */
312: public void addMouseListener(MapMouseListener l) {
313: eventJob.addMouseListener(l);
314: }
315:
316: /**
317: * @see ViewportPane#addMouseMotionListener(MapMouseMotionListener)
318: */
319: public void addMouseMotionListener(MapMouseMotionListener l) {
320: eventJob.addMouseMotionListener(l);
321: }
322:
323: /**
324: * @see ViewportPane#addMouseWheelListener(MapMouseWheelListener)
325: */
326: public void addMouseWheelListener(MapMouseWheelListener l) {
327: eventJob.addMouseWheelListener(l);
328: }
329:
330: /**
331: * @see net.refractions.udig.project.ui.render.displayAdapter.ViewportPane#renderStarting()
332: */
333: public void renderStarting() {
334: painter.renderStart();
335: repaint();
336: }
337:
338: /**
339: * @see net.refractions.udig.project.ui.render.displayAdapter.ViewportPane#renderDone()
340: */
341: public void renderDone() {
342: renderUpdate();
343: painter.renderDone();
344: }
345:
346: /**
347: * @see net.refractions.udig.project.ui.render.displayAdapter.ViewportPane#renderUpdate()
348: */
349: public void renderUpdate() {
350: initMap();
351: if (getImage() != null) {
352: painter.renderUpdate();
353: repaint();
354: }
355: }
356:
357: /**
358: * @see net.refractions.udig.project.ui.render.displayAdapter.ViewportPane#addPaneListener(net.refractions.udig.project.render.displayAdapter.MapDisplayListener)
359: */
360: public void addPaneListener(IMapDisplayListener listener) {
361: eventJob.addMapEditorListener(listener);
362: }
363:
364: /**
365: * @see net.refractions.udig.project.ui.render.displayAdapter.ViewportPane#removePaneListener(net.refractions.udig.project.render.displayAdapter.MapDisplayListener)
366: */
367: public void removePaneListener(IMapDisplayListener listener) {
368: eventJob.removeMapEditorListener(listener);
369: }
370:
371: /**
372: * @see net.refractions.udig.project.ui.render.displayAdapter.ViewportPane#setCursor(org.eclipse.swt.graphics.Cursor)
373: */
374: public void setCursor(final Cursor cursor) {
375: if ((Display.getCurrent() != null && Thread.currentThread() == Display
376: .getCurrent().getThread())
377: || Thread.currentThread() == Display.getDefault()
378: .getThread()) {
379: if (!composite.isDisposed())
380: composite.setCursor(cursor);
381: return;
382: } else {
383: Display d = Display.getCurrent();
384: if (d == null)
385: d = Display.getDefault();
386: d.asyncExec(new Runnable() {
387: public void run() {
388: if (!composite.isDisposed())
389: composite.setCursor(cursor);
390: }
391: });
392: }
393:
394: }
395:
396: /**
397: * @see net.refractions.udig.project.ui.render.displayAdapter.ViewportPane#getMapEditor()
398: */
399: public MapEditor getMapEditor() {
400: return editor;
401: }
402:
403: public int getDPI() {
404: return DEFAULT_DPI;
405: }
406:
407: public Control getControl() {
408: return composite;
409: }
410:
411: @Override
412: public void repaint() {
413: super .repaint();
414: }
415:
416: public void enableDrawCommands(boolean enable) {
417: painter.switchOnOff(enable);
418: }
419:
420: public boolean isDisposed() {
421: return composite.isDisposed();
422: }
423:
424: }
|