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