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