Refactored the construction of some of the core SWT World Window classes
[worldwindswt:worldwindswt.git] / plugins / gov.nasa.worldwind.swt / src / gov / nasa / worldwind / swt / SWTGLCanvasAutoDrawable.java
1 package gov.nasa.worldwind.swt;
2
3 import gov.nasa.worldwind.util.Logging;
4
5 import java.awt.event.ComponentListener;
6 import java.awt.event.FocusListener;
7 import java.awt.event.HierarchyBoundsListener;
8 import java.awt.event.HierarchyListener;
9 import java.awt.event.InputMethodListener;
10 import java.awt.event.KeyListener;
11 import java.awt.event.MouseListener;
12 import java.awt.event.MouseMotionListener;
13 import java.awt.event.MouseWheelListener;
14 import java.beans.PropertyChangeListener;
15 import java.beans.PropertyChangeSupport;
16 import java.util.ArrayList;
17 import java.util.List;
18 import java.util.logging.Level;
19
20 import javax.media.opengl.GL;
21 import javax.media.opengl.GLAutoDrawable;
22 import javax.media.opengl.GLCapabilities;
23 import javax.media.opengl.GLContext;
24 import javax.media.opengl.GLEventListener;
25
26 import org.eclipse.swt.SWT;
27 import org.eclipse.swt.events.PaintEvent;
28 import org.eclipse.swt.events.PaintListener;
29 import org.eclipse.swt.graphics.Point;
30 import org.eclipse.swt.opengl.GLCanvas;
31 import org.eclipse.swt.opengl.GLData;
32 import org.eclipse.swt.widgets.Composite;
33 import org.eclipse.swt.widgets.Event;
34 import org.eclipse.swt.widgets.Listener;
35
36 public class SWTGLCanvasAutoDrawable extends GLCanvas implements GLAutoDrawable {
37
38         private final GLContext context;
39
40         private Point lastSize;
41
42         private boolean doneInit;
43
44         private boolean shuttingDown;
45
46         public void shutdown() {
47                 shuttingDown = true;
48
49                 // Invokes a repaint, where the rest of the shutdown work is done.
50                 display();
51         }
52
53         protected void doShutdown() {
54                 // shuttingDown = false;
55         }
56
57         public SWTGLCanvasAutoDrawable(Composite parent, int style, GLData data, GLContext context) {
58                 super(parent, style | SWT.NO_BACKGROUND, data);
59
60                 setCurrent();
61                 if (context == null) {
62                         throw new IllegalArgumentException("GLContext cannot be null");
63                 }
64                 this.context = context;
65
66                 this.addPaintListener(new PaintListener() {
67                         @Override
68                         public void paintControl(PaintEvent e) {
69                                 display();
70                         }
71                 });
72
73                 parent.addListener(SWT.RESIZE, new Listener() {
74                         @Override
75                         public void handleEvent(Event event) {
76                                 notifyReshape();
77                         }
78
79                 });
80         }
81
82         private void runGL(Runnable runnable) {
83                 setCurrent();
84                 context.makeCurrent();
85
86                 try {
87                         runnable.run();
88                 } finally {
89                         context.release();
90                 }
91         }
92
93         private final List<GLEventListener> glEventListeners = new ArrayList<GLEventListener>();
94
95         private void notifyInit() {
96                 if (!doneInit) {
97                         doneInit = true;
98                         runGL(new Runnable() {
99                                 @Override
100                                 public void run() {
101                                         for (GLEventListener l : glEventListeners) {
102                                                 l.init(SWTGLCanvasAutoDrawable.this);
103                                         }
104                                 }
105                         });
106                 }
107         }
108
109         private void notifyReshape() {
110                 runGL(new Runnable() {
111                         @Override
112                         public void run() {
113                                 context.getGL().glViewport(0, 0, getWidth(), getHeight());
114                                 for (GLEventListener l : glEventListeners) {
115                                         l.reshape(SWTGLCanvasAutoDrawable.this, 0, 0, getWidth(), getHeight());
116                                 }
117                         }
118                 });
119         }
120
121         @Override
122         public void addGLEventListener(GLEventListener arg0) {
123                 glEventListeners.add(arg0);
124         }
125
126         @Override
127         public void removeGLEventListener(GLEventListener arg0) {
128                 glEventListeners.remove(arg0);
129         }
130
131         @Override
132         public void display() {
133                 if (this.shuttingDown) {
134                         try {
135                                 this.doShutdown();
136                         } catch (Exception e) {
137                                 Logging.logger().log(Level.SEVERE,
138                                                 Logging.getMessage("SWTWorldWindowGLCanvas.ExceptionWhileShuttingDownWorldWindow"), e);
139                         }
140                         return;
141                 }
142
143                 notifyInit();
144                 Point newSize = getSize();
145                 if (!newSize.equals(lastSize)) {
146                         lastSize = newSize;
147                         notifyReshape();
148                 }
149
150                 runGL(new Runnable() {
151                         @Override
152                         public void run() {
153                                 for (GLEventListener l : glEventListeners) {
154                                         l.display(SWTGLCanvasAutoDrawable.this);
155                                 }
156                         }
157                 });
158         }
159
160         @Override
161         public boolean getAutoSwapBufferMode() {
162                 return false;
163         }
164
165         @Override
166         public void setAutoSwapBufferMode(boolean arg0) {
167         }
168
169         @Override
170         public GLContext getContext() {
171                 return context;
172         }
173
174         @Override
175         public GL getGL() {
176                 return context.getGL();
177         }
178
179         private boolean redrawScheduled;
180
181         @Override
182         public synchronized void repaint() {
183                 if (!redrawScheduled && !isDisposed()) {
184                         redrawScheduled = true;
185                         getDisplay().asyncExec(new Runnable() {
186                                 @Override
187                                 public void run() {
188                                         synchronized (SWTGLCanvasAutoDrawable.this) {
189                                                 redrawScheduled = false;
190                                                 if (!isDisposed()) {
191                                                         redraw();
192                                                 }
193                                         }
194                                 }
195                         });
196                 }
197         }
198
199         @Override
200         public void setGL(GL arg0) {
201                 throw new UnsupportedOperationException();
202         }
203
204         @Override
205         public GLContext createContext(GLContext arg0) {
206                 throw new UnsupportedOperationException();
207         }
208
209         @Override
210         public GLCapabilities getChosenGLCapabilities() {
211                 return context.getGLDrawable().getChosenGLCapabilities();
212         }
213
214         @Override
215         public void swapBuffers() {
216                 super.swapBuffers();
217         }
218
219         @Override
220         public int getHeight() {
221                 return getSize().y;
222         }
223
224         @Override
225         public int getWidth() {
226                 return getSize().x;
227         }
228
229         @Override
230         public void setRealized(boolean arg0) {
231         }
232
233         @Override
234         public void addComponentListener(ComponentListener arg0) {
235                 throw new UnsupportedOperationException();
236         }
237
238         @Override
239         public void addFocusListener(FocusListener arg0) {
240                 throw new UnsupportedOperationException();
241         }
242
243         @Override
244         public void addHierarchyBoundsListener(HierarchyBoundsListener arg0) {
245                 throw new UnsupportedOperationException();
246         }
247
248         @Override
249         public void addHierarchyListener(HierarchyListener arg0) {
250                 throw new UnsupportedOperationException();
251         }
252
253         @Override
254         public void addInputMethodListener(InputMethodListener arg0) {
255                 throw new UnsupportedOperationException();
256         }
257
258         @Override
259         public void addKeyListener(KeyListener arg0) {
260                 throw new UnsupportedOperationException();
261         }
262
263         @Override
264         public void addMouseListener(MouseListener arg0) {
265                 throw new UnsupportedOperationException();
266         }
267
268         @Override
269         public void addMouseMotionListener(MouseMotionListener arg0) {
270                 throw new UnsupportedOperationException();
271         }
272
273         @Override
274         public void addMouseWheelListener(MouseWheelListener arg0) {
275                 throw new UnsupportedOperationException();
276         }
277
278         @Override
279         public void removeComponentListener(ComponentListener arg0) {
280                 throw new UnsupportedOperationException();
281         }
282
283         @Override
284         public void removeFocusListener(FocusListener arg0) {
285                 throw new UnsupportedOperationException();
286         }
287
288         @Override
289         public void removeHierarchyBoundsListener(HierarchyBoundsListener arg0) {
290                 throw new UnsupportedOperationException();
291         }
292
293         @Override
294         public void removeHierarchyListener(HierarchyListener arg0) {
295                 throw new UnsupportedOperationException();
296         }
297
298         @Override
299         public void removeInputMethodListener(InputMethodListener arg0) {
300                 throw new UnsupportedOperationException();
301         }
302
303         @Override
304         public void removeKeyListener(KeyListener arg0) {
305                 throw new UnsupportedOperationException();
306         }
307
308         @Override
309         public void removeMouseListener(MouseListener arg0) {
310                 throw new UnsupportedOperationException();
311         }
312
313         @Override
314         public void removeMouseMotionListener(MouseMotionListener arg0) {
315                 throw new UnsupportedOperationException();
316         }
317
318         @Override
319         public void removeMouseWheelListener(MouseWheelListener arg0) {
320                 throw new UnsupportedOperationException();
321         }
322
323         private final PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);
324
325         @Override
326         public void addPropertyChangeListener(PropertyChangeListener listener) {
327                 changeSupport.addPropertyChangeListener(listener);
328         }
329
330         @Override
331         public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
332                 changeSupport.addPropertyChangeListener(propertyName, listener);
333         }
334
335         @Override
336         public void removePropertyChangeListener(PropertyChangeListener listener) {
337                 changeSupport.removePropertyChangeListener(listener);
338         }
339
340         @Override
341         public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
342                 changeSupport.removePropertyChangeListener(propertyName, listener);
343         }
344
345 }