]> git.mxchange.org Git - flightgear.git/blob - src/Cockpit/panel.hxx
db242d9fa88e487a0263fc5569b223b39dfe9380
[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, float increment,
146                   float min, float max, bool wrap=false);
147   virtual ~FGAdjustAction ();
148   virtual void doAction ();
149
150 private:
151   getter_type _getter;
152   setter_type _setter;
153   float _increment;
154   float _min;
155   float _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                                   float min, float max,
297                                   float factor = 1.0, float offset = 0.0);
298
299 protected:
300   int _w, _h;
301
302   typedef struct {
303     transform_type type;
304     transform_func func;
305     float min;
306     float max;
307     float factor;
308     float 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                         int w = -1, int h = -1,
346                         float texX1 = 0.0, float texY1 = 0.0,
347                         float texX2 = 1.0, float texY2 = 1.0);
348   virtual void addTransformation (FGInstrumentLayer::transform_type type,
349                                   FGInstrumentLayer::transform_func func,
350                                   float min, float max,
351                                   float factor = 1.0, float offset = 0.0);
352   virtual void addTransformation (FGInstrumentLayer::transform_type type,
353                                   float offset);
354
355 protected:
356   layer_list _layers;
357 };
358
359
360 \f
361 ////////////////////////////////////////////////////////////////////////
362 // A textured layer of an instrument.
363 //
364 // This is a layer holding a single texture.  Normally, the texture's
365 // backgound should be transparent so that lower layers and the panel
366 // background can show through.
367 ////////////////////////////////////////////////////////////////////////
368
369 class FGTexturedLayer : public FGInstrumentLayer
370 {
371 public:
372   FGTexturedLayer (ssgTexture * texture, int w, int h,
373                    float texX1 = 0.0, float texY1 = 0.0,
374                    float texX2 = 1.0, float texY2 = 1.0);
375   virtual ~FGTexturedLayer ();
376
377   virtual void draw () const;
378
379   virtual void setTexture (ssgTexture * texture) { _texture = texture; }
380   virtual void setTextureCoords (float x1, float y1, float x2, float y2) {
381     _texX1 = x1; _texY1 = y1; _texX2 = x2; _texY2 = y2;
382   }
383
384 protected:
385   
386   virtual void setTextureCoords (float x1, float y1,
387                                  float x2, float y2) const {
388     _texX1 = x1; _texY1 = y1; _texX2 = x2; _texY2 = y2;
389   }
390
391
392 private:
393   ssgTexture * _texture;
394   mutable float _texX1, _texY1, _texX2, _texY2;
395 };
396
397
398 \f
399 ////////////////////////////////////////////////////////////////////////
400 // A text layer of an instrument.
401 //
402 // This is a layer holding a string of static and/or generated text.
403 // It is useful for instruments that have text displays, such as
404 // a chronometer, GPS, or NavCom radio.
405 ////////////////////////////////////////////////////////////////////////
406
407 class FGTextLayer : public FGInstrumentLayer
408 {
409 public:
410   typedef char * (*text_func)();
411   typedef double (*double_func)();
412   typedef enum ChunkType {
413     TEXT,
414     TEXT_FUNC,
415     DOUBLE_FUNC
416   };
417
418   class Chunk {
419   public:
420     Chunk (char * text, char * fmt = "%s");
421     Chunk (text_func func, char * fmt = "%s");
422     Chunk (double_func func, char * fmt = "%.2f", float mult = 1.0);
423
424     char * getValue () const;
425   private:
426     ChunkType _type;
427     union {
428       char * _text;
429       text_func _tfunc;
430       double_func _dfunc;
431     } _value;
432     char * _fmt;
433     float _mult;
434     mutable char _buf[1024];
435   };
436
437   FGTextLayer (int w, int h);
438   virtual ~FGTextLayer ();
439
440   virtual void draw () const;
441
442                                 // Transfer pointer!!
443   virtual void addChunk (Chunk * chunk);
444   virtual void setColor (float r, float g, float b);
445   virtual void setPointSize (float size);
446   virtual void setFont (fntFont * font);
447
448 private:
449   typedef vector<Chunk *> chunk_list;
450   chunk_list _chunks;
451   float _color[4];
452                                 // FIXME: need only one globally
453   mutable fntRenderer _renderer;
454 };
455
456
457 \f
458 ////////////////////////////////////////////////////////////////////////
459 // A layer that switches between two other layers.
460 ////////////////////////////////////////////////////////////////////////
461
462 class FGSwitchLayer : public FGInstrumentLayer
463 {
464 public:
465   typedef bool (*switch_func)();
466
467                                 // Transfer pointers!!
468   FGSwitchLayer (int w, int h, switch_func func,
469                  FGInstrumentLayer * layer1,
470                  FGInstrumentLayer * layer2);
471   virtual ~FGSwitchLayer ();
472
473   virtual void draw () const;
474
475 private:
476   switch_func _func;
477   FGInstrumentLayer * _layer1, * _layer2;
478 };
479
480
481 \f
482 ////////////////////////////////////////////////////////////////////////
483 // The current panel, if any.
484 ////////////////////////////////////////////////////////////////////////
485
486 extern FGPanel * current_panel;
487
488
489 \f
490 #endif // __PANEL_HXX
491
492 // end of panel.hxx
493
494