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