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