]> git.mxchange.org Git - flightgear.git/blob - src/Cockpit/panel.hxx
70a311de68e86501e740f6b0417db2a273360895
[flightgear.git] / src / Cockpit / panel.hxx
1 //  panel.hxx - generic support classes for a 2D panel.
2 //
3 //  Written by David Megginson, started January 2000.
4 //
5 //  This program is free software; you can redistribute it and/or
6 //  modify it under the terms of the GNU General Public License as
7 //  published by the Free Software Foundation; either version 2 of the
8 //  License, or (at your option) any later version.
9 // 
10 //  This program is distributed in the hope that it will be useful, but
11 //  WITHOUT ANY WARRANTY; without even the implied warranty of
12 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 //  General Public License for more details.
14 // 
15 //  You should have received a copy of the GNU General Public License
16 //  along with this program; if not, write to the Free Software
17 //  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 //
19 //  $Id$
20
21 #ifndef __PANEL_HXX
22 #define __PANEL_HXX
23
24 #ifndef __cplusplus                                                          
25 # error This library requires C++
26 #endif                                   
27
28
29 #ifdef HAVE_CONFIG_H
30 #  include <config.h>
31 #endif
32
33 #include <simgear/compiler.h>
34
35 #ifdef HAVE_WINDOWS_H          
36 #  include <windows.h>
37 #endif
38
39 #include <GL/glut.h>
40 #include <plib/ssg.h>
41
42 #include <simgear/math/interpolater.hxx>
43 #include <simgear/misc/props.hxx>
44 #include <simgear/timing/timestamp.hxx>
45
46 #include <vector>
47 #include <map>
48 #include <plib/fnt.h>
49
50 #include <Main/fgfs.hxx>
51
52 #include <Input/input.hxx>
53
54 SG_USING_STD(vector);
55 SG_USING_STD(map);
56
57 class FGPanelInstrument;
58
59
60 \f
61 ////////////////////////////////////////////////////////////////////////
62 // Texture manager (should migrate out into FGFS).
63 //
64 // This class ensures that no texture is loaded more than once.
65 ////////////////////////////////////////////////////////////////////////
66
67 class FGTextureManager
68 {
69 public:
70   static ssgTexture * createTexture(const string &relativePath);
71 private:
72   static map<string,ssgTexture *> _textureMap;
73 };
74
75
76 \f
77 ////////////////////////////////////////////////////////////////////////
78 // Cropped texture (should migrate out into FGFS).
79 //
80 // This structure wraps an SSG texture with cropping information.
81 ////////////////////////////////////////////////////////////////////////
82
83 class FGCroppedTexture
84 {
85 public:
86
87   FGCroppedTexture ();
88   FGCroppedTexture (const string &path,
89                   float _minX = 0.0, float _minY = 0.0,
90                   float _maxX = 1.0, float _maxY = 1.0);
91   virtual ~FGCroppedTexture ();
92
93   virtual void setPath (const string &path) { _path = path; }
94
95   virtual const string &getPath () const { return _path; }
96
97   virtual ssgTexture * getTexture ();
98
99   virtual void setCrop (float minX, float minY, float maxX, float maxY) {
100     _minX = minX; _minY = minY; _maxX = maxX; _maxY = maxY;
101   }
102
103   virtual float getMinX () const { return _minX; }
104   virtual float getMinY () const { return _minY; }
105   virtual float getMaxX () const { return _maxX; }
106   virtual float getMaxY () const { return _maxY; }
107
108
109 private:
110   string _path;
111   ssgTexture * _texture;
112   float _minX, _minY, _maxX, _maxY;
113 };
114
115
116 \f
117 ////////////////////////////////////////////////////////////////////////
118 // Instrument panel class.
119 //
120 // The panel is a container that has a background texture and holds
121 // zero or more instruments.  The panel will order the instruments to
122 // redraw themselves when necessary, and will pass mouse clicks on to
123 // the appropriate instruments for processing.
124 ////////////////////////////////////////////////////////////////////////
125
126 class FGPanel : public FGSubsystem
127 {
128 public:
129
130   FGPanel ();
131   virtual ~FGPanel ();
132
133                                 // Update the panel (every frame).
134   virtual void init ();
135   virtual void bind ();
136   virtual void unbind ();
137   virtual void update ();
138   virtual void update (GLfloat winx, GLfloat winw, GLfloat winy, GLfloat winh);
139
140                                 // transfer pointer ownership!!!
141   virtual void addInstrument (FGPanelInstrument * instrument);
142
143                                 // Background texture.
144   virtual void setBackground (ssgTexture * texture);
145
146                                 // Make the panel visible or invisible.
147   virtual bool getVisibility () const;
148   virtual void setVisibility (bool visibility);
149
150                                 // Full width of panel.
151   virtual void setWidth (int width) { _width = width; }
152   virtual int getWidth () const { return _width; }
153
154                                 // Full height of panel.
155   virtual void setHeight (int height) { _height = height; }
156   virtual int getHeight () const { return _height; }
157
158                                 // X-offset
159   virtual void setXOffset (int offset);
160   virtual int getXOffset () const { return _x_offset; }
161
162                                 // Y-offset.
163   virtual void setYOffset (int offset);
164   virtual int getYOffset () const { return _y_offset; }
165
166                                 // View height.
167   virtual void setViewHeight (int height) { _view_height = height; }
168   virtual int getViewHeight () const { return _view_height; }
169
170                                 // Handle a mouse click.
171   virtual bool doMouseAction (int button, int updown, int x, int y);
172
173 private:
174   mutable bool _visibility;
175   mutable bool _mouseDown;
176   mutable int _mouseButton, _mouseX, _mouseY;
177   mutable int _mouseDelay;
178   mutable FGPanelInstrument * _mouseInstrument;
179   typedef vector<FGPanelInstrument *> instrument_list_type;
180   int _width;
181   int _height;
182   int _x_offset;
183   int _y_offset;
184   int _view_height;
185   bool _bound;
186
187   const SGPropertyNode * _xsize_node;
188   const SGPropertyNode * _ysize_node;
189   
190   ssgTexture * _bg;
191                                 // List of instruments in panel.
192   instrument_list_type _instruments;
193 };
194
195
196 \f
197 ////////////////////////////////////////////////////////////////////////
198 // Base class for user action types.
199 //
200 // Individual instruments can have actions associated with a mouse
201 // click in a rectangular area.  Current concrete classes include
202 // FGAdjustAction, FGSwapAction, and FGToggleAction.
203 ////////////////////////////////////////////////////////////////////////
204
205 class FGPanelAction
206 {
207 public:
208   FGPanelAction ();
209   FGPanelAction (int button, int x, int y, int w, int h);
210   virtual ~FGPanelAction ();
211
212                                 // Getters.
213   virtual int getButton () const { return _button; }
214   virtual int getX () const { return _x; }
215   virtual int getY () const { return _y; }
216   virtual int getWidth () const { return _w; }
217   virtual int getHeight () const { return _h; }
218
219                                 // Setters.
220   virtual void addBinding (const FGBinding &binding);
221   virtual void setButton (int button) { _button = button; }
222   virtual void setX (int x) { _x = x; }
223   virtual void setY (int y) { _y = y; }
224   virtual void setWidth (int w) { _w = w; }
225   virtual void setHeight (int h) { _h = h; }
226
227                                 // Check whether we're in the area.
228   virtual bool inArea (int button, int x, int y)
229   {
230     return (button == _button &&
231             x >= _x &&
232             x < _x + _w &&
233             y >= _y &&
234             y < _y + _h);
235   }
236
237                                 // Perform the action.
238   virtual void doAction ();
239
240 private:
241   typedef vector<FGBinding> binding_list_t;
242
243   int _button;
244   int _x;
245   int _y;
246   int _w;
247   int _h;
248   binding_list_t _bindings;
249 };
250
251
252 \f
253 ////////////////////////////////////////////////////////////////////////
254 // Abstract base class for a panel instrument.
255 //
256 // A panel instrument consists of zero or more actions, associated
257 // with mouse clicks in rectangular areas.  Currently, the only
258 // concrete class derived from this is FGLayeredInstrument, but others
259 // may show up in the future (some complex instruments could be 
260 // entirely hand-coded, for example).
261 ////////////////////////////////////////////////////////////////////////
262
263 class FGPanelInstrument
264 {
265 public:
266   FGPanelInstrument ();
267   FGPanelInstrument (int x, int y, int w, int h);
268   virtual ~FGPanelInstrument ();
269
270   virtual void draw () = 0;
271
272   virtual void setPosition(int x, int y);
273   virtual void setSize(int w, int h);
274
275   virtual int getXPos () const;
276   virtual int getYPos () const;
277   virtual int getWidth () const;
278   virtual int getHeight () const;
279
280                                 // Coordinates relative to centre.
281                                 // Transfer pointer ownership!!
282   virtual void addAction (FGPanelAction * action);
283
284                                 // Coordinates relative to centre.
285   virtual bool doMouseAction (int button, int x, int y);
286
287 protected:
288   int _x, _y, _w, _h;
289   typedef vector<FGPanelAction *> action_list_type;
290   action_list_type _actions;
291 };
292
293
294 \f
295 ////////////////////////////////////////////////////////////////////////
296 // Abstract base class for an instrument layer.
297 //
298 // The FGLayeredInstrument class builds up instruments by using layers
299 // of textures or text.  Each layer can have zero or more
300 // transformations applied to it: for example, a needle layer can
301 // rotate to show the altitude or airspeed.
302 ////////////////////////////////////////////////////////////////////////
303
304
305 /**
306  * A transformation for a layer.
307  */
308 class FGPanelTransformation {
309 public:
310
311   enum Type {
312     XSHIFT,
313     YSHIFT,
314     ROTATION
315   };
316
317   FGPanelTransformation ();
318   virtual ~FGPanelTransformation ();
319
320   Type type;
321   const SGPropertyNode * node;
322   float min;
323   float max;
324   float factor;
325   float offset;
326   SGInterpTable * table;
327 };
328
329
330
331 /**
332  * A single layer of a multi-layered instrument.
333  *
334  * Each layer can be subject to a series of transformations based
335  * on current FGFS instrument readings: for example, a texture
336  * representing a needle can rotate to show the airspeed.
337  */
338 class FGInstrumentLayer
339 {
340 public:
341
342   FGInstrumentLayer (int w = -1, int h = -1);
343   virtual ~FGInstrumentLayer ();
344
345   virtual void draw () = 0;
346   virtual void transform () const;
347
348   virtual int getWidth () const { return _w; }
349   virtual int getHeight () const { return _h; }
350   virtual void setWidth (int w) { _w = w; }
351   virtual void setHeight (int h) { _h = h; }
352
353                                 // Transfer pointer ownership!!
354                                 // DEPRECATED
355   virtual void addTransformation (FGPanelTransformation * transformation);
356
357 protected:
358   int _w, _h;
359
360   typedef vector<FGPanelTransformation *> transformation_list;
361   transformation_list _transformations;
362 };
363
364
365 \f
366 ////////////////////////////////////////////////////////////////////////
367 // An instrument composed of layers.
368 //
369 // This class represents an instrument which is simply a series of
370 // layers piled one on top of the other, each one undergoing its own
371 // set of transformations.  For example, one layer can represent
372 // the instrument's face (which doesn't move), while the next layer
373 // can represent a needle that rotates depending on an FGFS variable.
374 ////////////////////////////////////////////////////////////////////////
375
376
377 /**
378  * An instrument constructed of multiple layers.
379  *
380  * Each individual layer can be rotated or shifted to correspond
381  * to internal FGFS instrument readings.
382  */
383 class FGLayeredInstrument : public FGPanelInstrument
384 {
385 public:
386   FGLayeredInstrument (int x, int y, int w, int h);
387   virtual ~FGLayeredInstrument ();
388
389   virtual void draw ();
390
391                                 // Transfer pointer ownership!!
392   virtual int addLayer (FGInstrumentLayer *layer);
393   virtual int addLayer (FGCroppedTexture &texture, int w = -1, int h = -1);
394
395                                 // Transfer pointer ownership!!
396   virtual void addTransformation (FGPanelTransformation * transformation);
397
398 protected:
399   typedef vector<FGInstrumentLayer *> layer_list;
400   layer_list _layers;
401 };
402
403
404 \f
405 ////////////////////////////////////////////////////////////////////////
406 // A textured layer of an instrument.
407 //
408 // This is a layer holding a single texture.  Normally, the texture's
409 // backgound should be transparent so that lower layers and the panel
410 // background can show through.
411 ////////////////////////////////////////////////////////////////////////
412
413 class FGTexturedLayer : public FGInstrumentLayer
414 {
415 public:
416   FGTexturedLayer (int w = -1, int h = -1) : FGInstrumentLayer(w, h) {}
417   FGTexturedLayer (const FGCroppedTexture &texture, int w = -1, int h = -1);
418   virtual ~FGTexturedLayer ();
419
420   virtual void draw ();
421
422   virtual void setTexture (const FGCroppedTexture &texture) {
423     _texture = texture;
424   }
425   virtual FGCroppedTexture &getTexture () { return _texture; }
426   virtual const FGCroppedTexture &getTexture () const { return _texture; }
427
428 private:
429   mutable FGCroppedTexture _texture;
430 };
431
432
433 \f
434 ////////////////////////////////////////////////////////////////////////
435 // A text layer of an instrument.
436 //
437 // This is a layer holding a string of static and/or generated text.
438 // It is useful for instruments that have text displays, such as
439 // a chronometer, GPS, or NavCom radio.
440 ////////////////////////////////////////////////////////////////////////
441
442 class FGTextLayer : public FGInstrumentLayer
443 {
444 public:
445   typedef enum ChunkType {
446     TEXT,
447     TEXT_VALUE,
448     DOUBLE_VALUE
449   };
450
451   class Chunk {
452   public:
453     Chunk (const string &text, const string &fmt = "%s");
454     Chunk (ChunkType type, const SGPropertyNode * node,
455            const string &fmt = "", float mult = 1.0);
456
457     const char * getValue () const;
458   private:
459     ChunkType _type;
460     string _text;
461     const SGPropertyNode * _node;
462     string _fmt;
463     float _mult;
464     mutable char _buf[1024];
465   };
466
467   FGTextLayer (int w = -1, int h = -1);
468   virtual ~FGTextLayer ();
469
470   virtual void draw ();
471
472                                 // Transfer pointer!!
473   virtual void addChunk (Chunk * chunk);
474   virtual void setColor (float r, float g, float b);
475   virtual void setPointSize (float size);
476   virtual void setFont (fntFont * font);
477
478 private:
479
480   void recalc_value () const;
481
482   typedef vector<Chunk *> chunk_list;
483   chunk_list _chunks;
484   float _color[4];
485
486   float _pointSize;
487
488   mutable string _value;
489   mutable SGTimeStamp _then;
490   mutable SGTimeStamp _now;
491 };
492
493
494 \f
495 ////////////////////////////////////////////////////////////////////////
496 // A layer that switches between two other layers.
497 ////////////////////////////////////////////////////////////////////////
498
499 class FGSwitchLayer : public FGInstrumentLayer
500 {
501 public:
502                                 // Transfer pointers!!
503   FGSwitchLayer (int w, int h, const SGPropertyNode * node,
504                  FGInstrumentLayer * layer1,
505                  FGInstrumentLayer * layer2);
506   virtual ~FGSwitchLayer ();
507
508   virtual void draw ();
509
510 private:
511   const SGPropertyNode * _node;
512   FGInstrumentLayer * _layer1, * _layer2;
513 };
514
515
516 \f
517 ////////////////////////////////////////////////////////////////////////
518 // Functions.
519 ////////////////////////////////////////////////////////////////////////
520
521 bool fgPanelVisible ();
522
523
524 \f
525 ////////////////////////////////////////////////////////////////////////
526 // The current panel, if any.
527 ////////////////////////////////////////////////////////////////////////
528
529 extern FGPanel * current_panel;
530
531
532 \f
533 #endif // __PANEL_HXX
534
535 // end of panel.hxx
536
537