]> git.mxchange.org Git - flightgear.git/blob - src/Cockpit/panel.hxx
4ef5fffc776f362403713b4ef68201a60517ca02
[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 #include <Main/fg_props.hxx>
52
53 #include <Input/input.hxx>
54
55 SG_USING_STD(vector);
56 SG_USING_STD(map);
57
58 class FGPanelInstrument;
59
60
61 \f
62 ////////////////////////////////////////////////////////////////////////
63 // Texture management.
64 ////////////////////////////////////////////////////////////////////////
65
66
67 /**
68  * Texture manager (should migrate out into FGFS).
69  *
70  * This class ensures that no texture is loaded more than once.
71  */
72 class FGTextureManager
73 {
74 public:
75   static ssgTexture * createTexture(const string &relativePath);
76 private:
77   static map<string,ssgTexture *> _textureMap;
78 };
79
80
81 /**
82  * Cropped texture (should migrate out into FGFS).
83  *
84  * This structure wraps an SSG texture with cropping information.
85  */
86 class FGCroppedTexture
87 {
88 public:
89
90   FGCroppedTexture ();
91   FGCroppedTexture (const string &path,
92                   float _minX = 0.0, float _minY = 0.0,
93                   float _maxX = 1.0, float _maxY = 1.0);
94   virtual ~FGCroppedTexture ();
95
96   virtual void setPath (const string &path) { _path = path; }
97
98   virtual const string &getPath () const { return _path; }
99
100   virtual ssgTexture * getTexture ();
101
102   virtual void setCrop (float minX, float minY, float maxX, float maxY) {
103     _minX = minX; _minY = minY; _maxX = maxX; _maxY = maxY;
104   }
105
106   virtual float getMinX () const { return _minX; }
107   virtual float getMinY () const { return _minY; }
108   virtual float getMaxX () const { return _maxX; }
109   virtual float getMaxY () const { return _maxY; }
110
111
112 private:
113   string _path;
114   ssgTexture * _texture;
115   float _minX, _minY, _maxX, _maxY;
116 };
117
118
119 \f
120 ////////////////////////////////////////////////////////////////////////
121 // Top-level panel.
122 ////////////////////////////////////////////////////////////////////////
123
124
125 /**
126  * Instrument panel class.
127  *
128  * The panel is a container that has a background texture and holds
129  * zero or more instruments.  The panel will order the instruments to
130  * redraw themselves when necessary, and will pass mouse clicks on to
131  * the appropriate instruments for processing.
132  */
133 class FGPanel : public FGSubsystem
134 {
135 public:
136
137   FGPanel ();
138   virtual ~FGPanel ();
139
140                                 // Update the panel (every frame).
141   virtual void init ();
142   virtual void bind ();
143   virtual void unbind ();
144   virtual void draw ();
145   virtual void update (double dt);
146   virtual void update (GLfloat winx, GLfloat winw, GLfloat winy, GLfloat winh);
147
148   virtual void updateMouseDelay();
149
150                                 // transfer pointer ownership!!!
151   virtual void addInstrument (FGPanelInstrument * instrument);
152
153                                 // Background texture.
154   virtual void setBackground (ssgTexture * texture);
155
156                                 // Background multiple textures.
157   virtual void setMultiBackground (ssgTexture * texture, int idx);
158
159                                 // Make the panel visible or invisible.
160   virtual bool getVisibility () const;
161   virtual void setVisibility (bool visibility);
162
163                                 // Full width of panel.
164   virtual void setWidth (int width) { _width = width; }
165   virtual int getWidth () const { return _width; }
166
167                                 // Full height of panel.
168   virtual void setHeight (int height) { _height = height; }
169   virtual int getHeight () const { return _height; }
170
171                                 // X-offset
172   virtual void setXOffset (int offset);
173   virtual int getXOffset () const { return _x_offset; }
174
175                                 // Y-offset.
176   virtual void setYOffset (int offset);
177   virtual int getYOffset () const { return _y_offset; }
178
179                                 // View height.
180   virtual void setViewHeight (int height) { _view_height = height; }
181   virtual int getViewHeight () const { return _view_height; }
182
183                                 // Handle a mouse click.
184   virtual bool doMouseAction (int button, int updown, int x, int y);
185   virtual bool doLocalMouseAction(int button, int updown, int x, int y);
186
187 private:
188   void setupVirtualCockpit();
189   void cleanupVirtualCockpit();
190
191   mutable bool _visibility;
192   mutable bool _mouseDown;
193   mutable int _mouseButton, _mouseX, _mouseY;
194   mutable int _mouseDelay;
195   mutable FGPanelInstrument * _mouseInstrument;
196   typedef vector<FGPanelInstrument *> instrument_list_type;
197   int _width;
198   int _height;
199   int _x_offset;
200   int _y_offset;
201   int _view_height;
202   float _jitter;
203   bool _flipx;
204
205   const SGPropertyNode * _xsize_node;
206   const SGPropertyNode * _ysize_node;
207   
208   ssgTexture * _bg;
209   ssgTexture * _mbg[8];
210                                 // List of instruments in panel.
211   instrument_list_type _instruments;
212 };
213
214
215 \f
216 ////////////////////////////////////////////////////////////////////////
217 // Actions
218 ////////////////////////////////////////////////////////////////////////
219
220
221 /**
222  * Class for user actions.
223  *
224  * The actions are command bindings, like bindings for the keyboard
225  * or joystick, but they are tied to specific mouse actions in
226  * rectangular areas of the panel.
227  */
228 class FGPanelAction : public FGConditional
229 {
230 public:
231   FGPanelAction ();
232   FGPanelAction (int button, int x, int y, int w, int h);
233   virtual ~FGPanelAction ();
234
235                                 // Getters.
236   virtual int getButton () const { return _button; }
237   virtual int getX () const { return _x; }
238   virtual int getY () const { return _y; }
239   virtual int getWidth () const { return _w; }
240   virtual int getHeight () const { return _h; }
241
242                                 // Setters.
243
244                                 // transfer pointer ownership
245   virtual void addBinding (FGBinding * binding);
246   virtual void setButton (int button) { _button = button; }
247   virtual void setX (int x) { _x = x; }
248   virtual void setY (int y) { _y = y; }
249   virtual void setWidth (int w) { _w = w; }
250   virtual void setHeight (int h) { _h = h; }
251
252                                 // Check whether we're in the area.
253   virtual bool inArea (int button, int x, int y)
254   {
255     return (button == _button &&
256             x >= _x &&
257             x < _x + _w &&
258             y >= _y &&
259             y < _y + _h);
260   }
261
262                                 // Perform the action.
263   virtual void doAction ();
264
265 private:
266   typedef vector<FGBinding *> binding_list_t;
267
268   int _button;
269   int _x;
270   int _y;
271   int _w;
272   int _h;
273   binding_list_t _bindings;
274 };
275
276
277 \f
278 ////////////////////////////////////////////////////////////////////////
279 // Transformations.
280 ////////////////////////////////////////////////////////////////////////
281
282
283 /**
284  * A transformation for a layer.
285  */
286 class FGPanelTransformation : public FGConditional
287 {
288 public:
289
290   enum Type {
291     XSHIFT,
292     YSHIFT,
293     ROTATION
294   };
295
296   FGPanelTransformation ();
297   virtual ~FGPanelTransformation ();
298
299   Type type;
300   const SGPropertyNode * node;
301   float min;
302   float max;
303   float factor;
304   float offset;
305   SGInterpTable * table;
306 };
307
308
309
310 \f
311 ////////////////////////////////////////////////////////////////////////
312 // Layers
313 ////////////////////////////////////////////////////////////////////////
314
315
316 /**
317  * A single layer of a multi-layered instrument.
318  *
319  * Each layer can be subject to a series of transformations based
320  * on current FGFS instrument readings: for example, a texture
321  * representing a needle can rotate to show the airspeed.
322  */
323 class FGInstrumentLayer : public FGConditional
324 {
325 public:
326
327   FGInstrumentLayer (int w = -1, int h = -1);
328   virtual ~FGInstrumentLayer ();
329
330   virtual void draw () = 0;
331   virtual void transform () const;
332
333   virtual int getWidth () const { return _w; }
334   virtual int getHeight () const { return _h; }
335   virtual void setWidth (int w) { _w = w; }
336   virtual void setHeight (int h) { _h = h; }
337
338                                 // Transfer pointer ownership!!
339                                 // DEPRECATED
340   virtual void addTransformation (FGPanelTransformation * transformation);
341
342 protected:
343   int _w, _h;
344
345   typedef vector<FGPanelTransformation *> transformation_list;
346   transformation_list _transformations;
347 };
348
349
350 \f
351 ////////////////////////////////////////////////////////////////////////
352 // Instruments.
353 ////////////////////////////////////////////////////////////////////////
354
355
356 /**
357  * Abstract base class for a panel instrument.
358  *
359  * A panel instrument consists of zero or more actions, associated
360  * with mouse clicks in rectangular areas.  Currently, the only
361  * concrete class derived from this is FGLayeredInstrument, but others
362  * may show up in the future (some complex instruments could be 
363  * entirely hand-coded, for example).
364  */
365 class FGPanelInstrument : public FGConditional
366 {
367 public:
368   FGPanelInstrument ();
369   FGPanelInstrument (int x, int y, int w, int h);
370   virtual ~FGPanelInstrument ();
371
372   virtual void draw () = 0;
373   virtual void drawHotspots();
374
375   virtual void setPosition(int x, int y);
376   virtual void setSize(int w, int h);
377
378   virtual int getXPos () const;
379   virtual int getYPos () const;
380   virtual int getWidth () const;
381   virtual int getHeight () const;
382
383                                 // Coordinates relative to centre.
384                                 // Transfer pointer ownership!!
385   virtual void addAction (FGPanelAction * action);
386
387                                 // Coordinates relative to centre.
388   virtual bool doMouseAction (int button, int x, int y);
389
390 protected:
391   int _x, _y, _w, _h;
392   typedef vector<FGPanelAction *> action_list_type;
393   action_list_type _actions;
394 };
395
396
397 /**
398  * An instrument constructed of multiple layers.
399  *
400  * Each individual layer can be rotated or shifted to correspond
401  * to internal FGFS instrument readings.
402  */
403 class FGLayeredInstrument : public FGPanelInstrument
404 {
405 public:
406   FGLayeredInstrument (int x, int y, int w, int h);
407   virtual ~FGLayeredInstrument ();
408
409   virtual void draw ();
410
411                                 // Transfer pointer ownership!!
412   virtual int addLayer (FGInstrumentLayer *layer);
413   virtual int addLayer (FGCroppedTexture &texture, int w = -1, int h = -1);
414
415                                 // Transfer pointer ownership!!
416   virtual void addTransformation (FGPanelTransformation * transformation);
417
418 protected:
419   typedef vector<FGInstrumentLayer *> layer_list;
420   layer_list _layers;
421 };
422
423
424 /**
425  * An instrument layer containing a group of sublayers.
426  *
427  * This class is useful for gathering together a group of related
428  * layers, either to hold in an external file or to work under
429  * the same condition.
430  */
431 class FGGroupLayer : public FGInstrumentLayer
432 {
433 public:
434   FGGroupLayer ();
435   virtual ~FGGroupLayer ();
436   virtual void draw ();
437                                 // transfer pointer ownership
438   virtual void addLayer (FGInstrumentLayer * layer);
439 private:
440   vector<FGInstrumentLayer *> _layers;
441 };
442
443
444 /**
445  * A textured layer of an instrument.
446  *
447  * This is a layer holding a single texture.  Normally, the texture's
448  * backgound should be transparent so that lower layers and the panel
449  * background can show through.
450  */
451 class FGTexturedLayer : public FGInstrumentLayer
452 {
453 public:
454   FGTexturedLayer (int w = -1, int h = -1) : FGInstrumentLayer(w, h) {}
455   FGTexturedLayer (const FGCroppedTexture &texture, int w = -1, int h = -1);
456   virtual ~FGTexturedLayer ();
457
458   virtual void draw ();
459
460   virtual void setTexture (const FGCroppedTexture &texture) {
461     _texture = texture;
462   }
463   virtual FGCroppedTexture &getTexture () { return _texture; }
464   virtual const FGCroppedTexture &getTexture () const { return _texture; }
465
466 private:
467   mutable FGCroppedTexture _texture;
468 };
469
470
471 /**
472  * A text layer of an instrument.
473  *
474  * This is a layer holding a string of static and/or generated text.
475  * It is useful for instruments that have text displays, such as
476  * a chronometer, GPS, or NavCom radio.
477  */
478 class FGTextLayer : public FGInstrumentLayer
479 {
480 public:
481   enum ChunkType {
482     TEXT,
483     TEXT_VALUE,
484     DOUBLE_VALUE
485   };
486
487   class Chunk : public FGConditional
488   {
489   public:
490     Chunk (const string &text, const string &fmt = "%s");
491     Chunk (ChunkType type, const SGPropertyNode * node,
492            const string &fmt = "", float mult = 1.0);
493
494     const char * getValue () const;
495   private:
496     ChunkType _type;
497     string _text;
498     const SGPropertyNode * _node;
499     string _fmt;
500     float _mult;
501     mutable char _buf[1024];
502   };
503
504   FGTextLayer (int w = -1, int h = -1);
505   virtual ~FGTextLayer ();
506
507   virtual void draw ();
508
509                                 // Transfer pointer!!
510   virtual void addChunk (Chunk * chunk);
511   virtual void setColor (float r, float g, float b);
512   virtual void setPointSize (float size);
513   virtual void setFontName ( const string &name );
514   virtual void setFont (fntFont * font);
515
516 private:
517
518   void recalc_value () const;
519
520   typedef vector<Chunk *> chunk_list;
521   chunk_list _chunks;
522   float _color[4];
523
524   float _pointSize;
525   mutable string _font_name;
526   mutable string _value;
527   mutable SGTimeStamp _then;
528   mutable SGTimeStamp _now;
529 };
530
531
532 /**
533  * A layer that switches between two other layers.
534  *
535  * The usefulness of this layer is questionable now that all layers
536  * can have conditions, and it may be deprecated soon.
537  */
538 class FGSwitchLayer : public FGInstrumentLayer
539 {
540 public:
541                                 // Transfer pointers!!
542   FGSwitchLayer (int w, int h, const SGPropertyNode * node,
543                  FGInstrumentLayer * layer1,
544                  FGInstrumentLayer * layer2);
545   virtual ~FGSwitchLayer ();
546
547   virtual void draw ();
548
549 private:
550   const SGPropertyNode * _node;
551   FGInstrumentLayer * _layer1, * _layer2;
552 };
553
554
555
556 \f
557 ////////////////////////////////////////////////////////////////////////
558 // Functions.
559 ////////////////////////////////////////////////////////////////////////
560
561 /**
562  * Test whether the panel should be visible.
563  */
564 bool fgPanelVisible ();
565
566
567 \f
568 ////////////////////////////////////////////////////////////////////////
569 // The current panel, if any.
570 ////////////////////////////////////////////////////////////////////////
571
572 extern FGPanel * current_panel; // TODO: move to globals
573
574
575 \f
576 #endif // __PANEL_HXX
577
578 // end of panel.hxx
579
580
581