]> git.mxchange.org Git - flightgear.git/blob - src/Cockpit/panel.hxx
bc70ff2166af8e88ab982e0d57cdfd59e35d8398
[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   bool _visibility;
124   bool _mouseDown;
125   int _mouseButton, _mouseX, _mouseY;
126   mutable int _mouseDelay;
127   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 are
143 // FGAdjustAction and FGSwapAction.
144 ////////////////////////////////////////////////////////////////////////
145
146 class FGPanelAction
147 {
148 public:
149   virtual void doAction () = 0;
150 };
151
152
153 \f
154 ////////////////////////////////////////////////////////////////////////
155 // Adjustment action.
156 //
157 // This is an action to increase or decrease an FGFS value by a certain
158 // increment within a certain range.  If the wrap flag is true, the
159 // value will wrap around if it goes below min or above max; otherwise,
160 // it will simply stop at min or max.
161 ////////////////////////////////////////////////////////////////////////
162
163 class FGAdjustAction : public FGPanelAction
164 {
165 public:
166   FGAdjustAction (SGValue * value, float increment,
167                   float min, float max, bool wrap=false);
168   virtual ~FGAdjustAction ();
169   virtual void doAction ();
170
171 private:
172   SGValue * _value;
173   float _increment;
174   float _min;
175   float _max;
176   bool _wrap;
177 };
178
179
180 \f
181 ////////////////////////////////////////////////////////////////////////
182 // Swap action.
183 //
184 // This is an action to swap two values.  It's currently used in the
185 // navigation radios.
186 ////////////////////////////////////////////////////////////////////////
187
188 class FGSwapAction : public FGPanelAction
189 {
190 public:
191   FGSwapAction (SGValue * value1, SGValue * value2);
192   virtual ~FGSwapAction ();
193   virtual void doAction ();
194
195 private:
196   SGValue * _value1;
197   SGValue * _value2;
198 };
199
200
201 \f
202 ////////////////////////////////////////////////////////////////////////
203 // Toggle action.
204 //
205 // This is an action to toggle a boolean value.
206 ////////////////////////////////////////////////////////////////////////
207
208 class FGToggleAction : public FGPanelAction
209 {
210 public:
211   FGToggleAction (SGValue * value);
212   virtual ~FGToggleAction ();
213   virtual void doAction ();
214
215 private:
216   SGValue * _value;
217 };
218
219
220 \f
221 ////////////////////////////////////////////////////////////////////////
222 // Abstract base class for a panel instrument.
223 //
224 // A panel instrument consists of zero or more actions, associated
225 // with mouse clicks in rectangular areas.  Currently, the only
226 // concrete class derived from this is FGLayeredInstrument, but others
227 // may show up in the future (some complex instruments could be 
228 // entirely hand-coded, for example).
229 ////////////////////////////////////////////////////////////////////////
230
231 class FGPanelInstrument
232 {
233 public:
234   FGPanelInstrument ();
235   FGPanelInstrument (int x, int y, int w, int h);
236   virtual ~FGPanelInstrument ();
237
238   virtual void draw () = 0;
239
240   virtual void setPosition(int x, int y);
241   virtual void setSize(int w, int h);
242
243   virtual int getXPos () const;
244   virtual int getYPos () const;
245   virtual int getWidth () const;
246   virtual int getHeight () const;
247
248                                 // Coordinates relative to centre.
249                                 // Transfer pointer ownership!!
250   virtual void addAction (int button, int x, int y, int w, int h,
251                           FGPanelAction * action);
252
253                                 // Coordinates relative to centre.
254   virtual bool doMouseAction (int button, int x, int y);
255
256 protected:
257   int _x, _y, _w, _h;
258   typedef struct {
259     int button;
260     int x;
261     int y;
262     int w;
263     int h;
264     FGPanelAction * action;
265   } inst_action;
266   typedef vector<inst_action> action_list_type;
267   action_list_type _actions;
268 };
269
270
271 \f
272 ////////////////////////////////////////////////////////////////////////
273 // Abstract base class for an instrument layer.
274 //
275 // The FGLayeredInstrument class builds up instruments by using layers
276 // of textures or text.  Each layer can have zero or more
277 // transformations applied to it: for example, a needle layer can
278 // rotate to show the altitude or airspeed.
279 ////////////////////////////////////////////////////////////////////////
280
281 /**
282  * A single layer of a multi-layered instrument.
283  *
284  * Each layer can be subject to a series of transformations based
285  * on current FGFS instrument readings: for example, a texture
286  * representing a needle can rotate to show the airspeed.
287  */
288 class FGInstrumentLayer
289 {
290 public:
291   typedef enum {
292     XSHIFT,
293     YSHIFT,
294     ROTATION
295   } transform_type;
296
297   FGInstrumentLayer (int w = -1, int h = -1);
298   virtual ~FGInstrumentLayer ();
299
300   virtual void draw () = 0;
301   virtual void transform () const;
302
303   virtual int getWidth () const { return _w; }
304   virtual int getHeight () const { return _h; }
305   virtual void setWidth (int w) { _w = w; }
306   virtual void setHeight (int h) { _h = h; }
307
308   virtual void addTransformation (transform_type type, const SGValue * value,
309                                   float min, float max,
310                                   float factor = 1.0, float offset = 0.0);
311
312 protected:
313   int _w, _h;
314
315   typedef struct {
316     transform_type type;
317     const SGValue * value;
318     float min;
319     float max;
320     float factor;
321     float offset;
322   } transformation;
323   typedef vector<transformation *> transformation_list;
324   transformation_list _transformations;
325 };
326
327
328 \f
329 ////////////////////////////////////////////////////////////////////////
330 // An instrument composed of layers.
331 //
332 // This class represents an instrument which is simply a series of
333 // layers piled one on top of the other, each one undergoing its own
334 // set of transformations.  For example, one layer can represent
335 // the instrument's face (which doesn't move), while the next layer
336 // can represent a needle that rotates depending on an FGFS variable.
337 ////////////////////////////////////////////////////////////////////////
338
339
340 /**
341  * An instrument constructed of multiple layers.
342  *
343  * Each individual layer can be rotated or shifted to correspond
344  * to internal FGFS instrument readings.
345  */
346 class FGLayeredInstrument : public FGPanelInstrument
347 {
348 public:
349   typedef vector<FGInstrumentLayer *> layer_list;
350   FGLayeredInstrument (int x, int y, int w, int h);
351   virtual ~FGLayeredInstrument ();
352
353   virtual void draw ();
354
355                                 // Transfer pointer ownership!!
356   virtual int addLayer (FGInstrumentLayer *layer);
357   virtual int addLayer (CroppedTexture &texture,
358                         int w = -1, int h = -1);
359   virtual void addTransformation (FGInstrumentLayer::transform_type type,
360                                   const SGValue * value,
361                                   float min, float max,
362                                   float factor = 1.0, float offset = 0.0);
363   virtual void addTransformation (FGInstrumentLayer::transform_type type,
364                                   float offset);
365
366 protected:
367   layer_list _layers;
368 };
369
370
371 \f
372 ////////////////////////////////////////////////////////////////////////
373 // A textured layer of an instrument.
374 //
375 // This is a layer holding a single texture.  Normally, the texture's
376 // backgound should be transparent so that lower layers and the panel
377 // background can show through.
378 ////////////////////////////////////////////////////////////////////////
379
380 class FGTexturedLayer : public FGInstrumentLayer
381 {
382 public:
383   FGTexturedLayer (int w = -1, int h = -1) : FGInstrumentLayer(w, h) {}
384   FGTexturedLayer (CroppedTexture &texture, int w = -1, int h = -1);
385   virtual ~FGTexturedLayer ();
386
387   virtual void draw ();
388
389   virtual void setTexture (CroppedTexture &texture) { _texture = &texture; }
390   virtual CroppedTexture &getTexture () { return *_texture; }
391
392 private:
393   mutable CroppedTexture * _texture;
394 };
395
396
397 \f
398 ////////////////////////////////////////////////////////////////////////
399 // A text layer of an instrument.
400 //
401 // This is a layer holding a string of static and/or generated text.
402 // It is useful for instruments that have text displays, such as
403 // a chronometer, GPS, or NavCom radio.
404 ////////////////////////////////////////////////////////////////////////
405
406 class FGTextLayer : public FGInstrumentLayer
407 {
408 public:
409   typedef enum ChunkType {
410     TEXT,
411     TEXT_VALUE,
412     DOUBLE_VALUE
413   };
414
415   class Chunk {
416   public:
417     Chunk (char * text, char * fmt = "%s");
418     Chunk (ChunkType type, const SGValue * value,
419            char * fmt = 0, float mult = 1.0);
420
421     char * getValue () const;
422   private:
423     ChunkType _type;
424     union {
425       char * _text;
426       const SGValue * _value;
427     } _value;
428     char * _fmt;
429     float _mult;
430     mutable char _buf[1024];
431   };
432
433   FGTextLayer (int w = -1, int h = -1, Chunk * chunk1 = 0, Chunk * chunk2 = 0,
434                Chunk * chunk3 = 0);
435   virtual ~FGTextLayer ();
436
437   virtual void draw ();
438
439                                 // Transfer pointer!!
440   virtual void addChunk (Chunk * chunk);
441   virtual void setColor (float r, float g, float b);
442   virtual void setPointSize (float size);
443   virtual void setFont (fntFont * font);
444
445 private:
446   typedef vector<Chunk *> chunk_list;
447   chunk_list _chunks;
448   float _color[4];
449                                 // FIXME: need only one globally
450   mutable fntRenderer _renderer;
451 };
452
453
454 \f
455 ////////////////////////////////////////////////////////////////////////
456 // A layer that switches between two other layers.
457 ////////////////////////////////////////////////////////////////////////
458
459 class FGSwitchLayer : public FGInstrumentLayer
460 {
461 public:
462                                 // Transfer pointers!!
463   FGSwitchLayer (int w, int h, const SGValue * value,
464                  FGInstrumentLayer * layer1,
465                  FGInstrumentLayer * layer2);
466   virtual ~FGSwitchLayer ();
467
468   virtual void draw ();
469
470 private:
471   const SGValue * _value;
472   FGInstrumentLayer * _layer1, * _layer2;
473 };
474
475
476 \f
477 ////////////////////////////////////////////////////////////////////////
478 // The current panel, if any.
479 ////////////////////////////////////////////////////////////////////////
480
481 extern FGPanel * current_panel;
482
483
484 \f
485 #endif // __PANEL_HXX
486
487 // end of panel.hxx
488
489