]> git.mxchange.org Git - flightgear.git/blob - src/Cockpit/panel.hxx
Add support for moving cloud layers
[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 <plib/ssg.h>
40
41 #include <simgear/math/interpolater.hxx>
42 #include <simgear/props/props.hxx>
43 #include <simgear/timing/timestamp.hxx>
44
45 #include <cmath>
46 #include <vector>
47 #include <map>
48 #include <plib/fnt.h>
49
50 #include <Main/fgfs.hxx>
51 #include <Main/fg_props.hxx>
52
53 #include <Input/input.hxx>
54
55 SG_USING_STD(vector);
56 SG_USING_STD(map);
57
58 class FGPanelInstrument;
59
60
61 \f
62 ////////////////////////////////////////////////////////////////////////
63 // Texture management.
64 ////////////////////////////////////////////////////////////////////////
65
66
67 /**
68  * Texture manager (should migrate out into FGFS).
69  *
70  * This class ensures that no texture is loaded more than once.
71  */
72 class FGTextureManager
73 {
74 public:
75   static ssgTexture * createTexture(const string &relativePath);
76 private:
77   static map<string,ssgTexture *> _textureMap;
78 };
79
80
81 /**
82  * Cropped texture (should migrate out into FGFS).
83  *
84  * This structure wraps an SSG texture with cropping information.
85  */
86 class FGCroppedTexture
87 {
88 public:
89
90   FGCroppedTexture ();
91   FGCroppedTexture (const string &path,
92                   float _minX = 0.0, float _minY = 0.0,
93                   float _maxX = 1.0, float _maxY = 1.0);
94   virtual ~FGCroppedTexture ();
95
96   virtual void setPath (const string &path) { _path = path; }
97
98   virtual const string &getPath () const { return _path; }
99
100   virtual ssgTexture * getTexture ();
101
102   virtual void setCrop (float minX, float minY, float maxX, float maxY) {
103     _minX = minX; _minY = minY; _maxX = maxX; _maxY = maxY;
104   }
105
106   virtual float getMinX () const { return _minX; }
107   virtual float getMinY () const { return _minY; }
108   virtual float getMaxX () const { return _maxX; }
109   virtual float getMaxY () const { return _maxY; }
110
111
112 private:
113   string _path;
114   ssgTexture * _texture;
115   float _minX, _minY, _maxX, _maxY;
116 };
117
118
119 \f
120 ////////////////////////////////////////////////////////////////////////
121 // Top-level panel.
122 ////////////////////////////////////////////////////////////////////////
123
124
125 /**
126  * Instrument panel class.
127  *
128  * The panel is a container that has a background texture and holds
129  * zero or more instruments.  The panel will order the instruments to
130  * redraw themselves when necessary, and will pass mouse clicks on to
131  * the appropriate instruments for processing.
132  */
133 class FGPanel : public FGSubsystem
134 {
135 public:
136
137   FGPanel ();
138   virtual ~FGPanel ();
139
140                                 // Update the panel (every frame).
141   virtual void init ();
142   virtual void bind ();
143   virtual void unbind ();
144   virtual void draw ();
145   virtual void update (double dt);
146   virtual void update (GLfloat winx, GLfloat winw, GLfloat winy, GLfloat winh);
147
148   virtual void updateMouseDelay();
149
150                                 // transfer pointer ownership!!!
151   virtual void addInstrument (FGPanelInstrument * instrument);
152
153                                 // Background texture.
154   virtual void setBackground (ssgTexture * texture);
155
156                                 // Background multiple textures.
157   virtual void setMultiBackground (ssgTexture * texture, int idx);
158
159                                 // Make the panel visible or invisible.
160   virtual bool getVisibility () const;
161   virtual void setVisibility (bool visibility);
162
163                                 // Full width of panel.
164   virtual void setWidth (int width) { _width = width; }
165   virtual int getWidth () const { return _width; }
166
167                                 // Full height of panel.
168   virtual void setHeight (int height) { _height = height; }
169   virtual int getHeight () const { return _height; }
170
171                                 // X-offset
172   virtual void setXOffset (int offset);
173   virtual int getXOffset () const { return _x_offset->getIntValue(); }
174
175                                 // Y-offset.
176   virtual void setYOffset (int offset);
177   virtual int getYOffset () const { return _y_offset->getIntValue(); }
178
179                                 // View height.
180   virtual void setViewHeight (int height) { _view_height = height; }
181   virtual int getViewHeight () const { return _view_height; }
182
183                                 // Handle a mouse click.
184   virtual bool doMouseAction (int button, int updown, int x, int y);
185   virtual bool doLocalMouseAction(int button, int updown, int x, int y);
186
187 private:
188   void setupVirtualCockpit();
189   void cleanupVirtualCockpit();
190
191   mutable bool _mouseDown;
192   mutable int _mouseButton, _mouseX, _mouseY;
193   mutable int _mouseDelay;
194   mutable FGPanelInstrument * _mouseInstrument;
195   typedef vector<FGPanelInstrument *> instrument_list_type;
196   int _width;
197   int _height;
198   int _view_height;
199
200   SGPropertyNode * _visibility;
201   SGPropertyNode * _x_offset;
202   SGPropertyNode * _y_offset;
203   SGPropertyNode * _jitter;
204   SGPropertyNode * _flipx;
205
206   const SGPropertyNode * _xsize_node;
207   const SGPropertyNode * _ysize_node;
208   
209   ssgTexture * _bg;
210   ssgTexture * _mbg[8];
211                                 // List of instruments in panel.
212   instrument_list_type _instruments;
213 };
214
215
216 \f
217 ////////////////////////////////////////////////////////////////////////
218 // Actions
219 ////////////////////////////////////////////////////////////////////////
220
221
222 /**
223  * Class for user actions.
224  *
225  * The actions are command bindings, like bindings for the keyboard
226  * or joystick, but they are tied to specific mouse actions in
227  * rectangular areas of the panel.
228  */
229 class FGPanelAction : public SGConditional
230 {
231 public:
232   FGPanelAction ();
233   FGPanelAction (int button, int x, int y, int w, int h, bool repeatable);
234   virtual ~FGPanelAction ();
235
236                                 // Getters.
237   virtual int getButton () const { return _button; }
238   virtual int getX () const { return _x; }
239   virtual int getY () const { return _y; }
240   virtual int getWidth () const { return _w; }
241   virtual int getHeight () const { return _h; }
242
243                                 // Setters.
244
245                                 // transfer pointer ownership
246   virtual void addBinding (FGBinding * binding, int updown);
247   virtual void setButton (int button) { _button = button; }
248   virtual void setX (int x) { _x = x; }
249   virtual void setY (int y) { _y = y; }
250   virtual void setWidth (int w) { _w = w; }
251   virtual void setHeight (int h) { _h = h; }
252
253                                 // Check whether we're in the area.
254   virtual bool inArea (int button, int x, int y)
255   {
256     return (button == _button &&
257             x >= _x &&
258             x < _x + _w &&
259             y >= _y &&
260             y < _y + _h);
261   }
262
263                                 // Perform the action.
264   virtual bool doAction (int updown);
265
266 private:
267   typedef vector<FGBinding *> binding_list_t;
268
269   int _button;
270   int _x;
271   int _y;
272   int _w;
273   int _h;
274   bool _repeatable;
275   int _last_state;
276   binding_list_t _bindings[2];
277 };
278
279
280 \f
281 ////////////////////////////////////////////////////////////////////////
282 // Transformations.
283 ////////////////////////////////////////////////////////////////////////
284
285
286 /**
287  * A transformation for a layer.
288  */
289 class FGPanelTransformation : public SGConditional
290 {
291 public:
292
293   enum Type {
294     XSHIFT,
295     YSHIFT,
296     ROTATION
297   };
298
299   FGPanelTransformation ();
300   virtual ~FGPanelTransformation ();
301
302   Type type;
303   const SGPropertyNode * node;
304   float min;
305   float max;
306   bool has_mod;
307   float mod;
308   float factor;
309   float offset;
310   SGInterpTable * table;
311 };
312
313
314
315 \f
316 ////////////////////////////////////////////////////////////////////////
317 // Layers
318 ////////////////////////////////////////////////////////////////////////
319
320
321 /**
322  * A single layer of a multi-layered instrument.
323  *
324  * Each layer can be subject to a series of transformations based
325  * on current FGFS instrument readings: for example, a texture
326  * representing a needle can rotate to show the airspeed.
327  */
328 class FGInstrumentLayer : public SGConditional
329 {
330 public:
331
332   FGInstrumentLayer (int w = -1, int h = -1);
333   virtual ~FGInstrumentLayer ();
334
335   virtual void draw () = 0;
336   virtual void transform () const;
337
338   virtual int getWidth () const { return _w; }
339   virtual int getHeight () const { return _h; }
340   virtual void setWidth (int w) { _w = w; }
341   virtual void setHeight (int h) { _h = h; }
342
343                                 // Transfer pointer ownership!!
344                                 // DEPRECATED
345   virtual void addTransformation (FGPanelTransformation * transformation);
346
347 protected:
348   int _w, _h;
349
350   typedef vector<FGPanelTransformation *> transformation_list;
351   transformation_list _transformations;
352 };
353
354
355 \f
356 ////////////////////////////////////////////////////////////////////////
357 // Instruments.
358 ////////////////////////////////////////////////////////////////////////
359
360
361 /**
362  * Abstract base class for a panel instrument.
363  *
364  * A panel instrument consists of zero or more actions, associated
365  * with mouse clicks in rectangular areas.  Currently, the only
366  * concrete class derived from this is FGLayeredInstrument, but others
367  * may show up in the future (some complex instruments could be 
368  * entirely hand-coded, for example).
369  */
370 class FGPanelInstrument : public SGConditional
371 {
372 public:
373   FGPanelInstrument ();
374   FGPanelInstrument (int x, int y, int w, int h);
375   virtual ~FGPanelInstrument ();
376
377   virtual void draw () = 0;
378   virtual void drawHotspots();
379
380   virtual void setPosition(int x, int y);
381   virtual void setSize(int w, int h);
382
383   virtual int getXPos () const;
384   virtual int getYPos () const;
385   virtual int getWidth () const;
386   virtual int getHeight () const;
387
388                                 // Coordinates relative to centre.
389                                 // Transfer pointer ownership!!
390   virtual void addAction (FGPanelAction * action);
391
392                                 // Coordinates relative to centre.
393   virtual bool doMouseAction (int button, int updown, int x, int y);
394
395 protected:
396   int _x, _y, _w, _h;
397   typedef vector<FGPanelAction *> action_list_type;
398   action_list_type _actions;
399 };
400
401
402 /**
403  * An instrument constructed of multiple layers.
404  *
405  * Each individual layer can be rotated or shifted to correspond
406  * to internal FGFS instrument readings.
407  */
408 class FGLayeredInstrument : public FGPanelInstrument
409 {
410 public:
411   FGLayeredInstrument (int x, int y, int w, int h);
412   virtual ~FGLayeredInstrument ();
413
414   virtual void draw ();
415
416                                 // Transfer pointer ownership!!
417   virtual int addLayer (FGInstrumentLayer *layer);
418   virtual int addLayer (FGCroppedTexture &texture, int w = -1, int h = -1);
419
420                                 // Transfer pointer ownership!!
421   virtual void addTransformation (FGPanelTransformation * transformation);
422
423 protected:
424   typedef vector<FGInstrumentLayer *> layer_list;
425   layer_list _layers;
426 };
427
428
429 /**
430  * An instrument layer containing a group of sublayers.
431  *
432  * This class is useful for gathering together a group of related
433  * layers, either to hold in an external file or to work under
434  * the same condition.
435  */
436 class FGGroupLayer : public FGInstrumentLayer
437 {
438 public:
439   FGGroupLayer ();
440   virtual ~FGGroupLayer ();
441   virtual void draw ();
442                                 // transfer pointer ownership
443   virtual void addLayer (FGInstrumentLayer * layer);
444 protected:
445   vector<FGInstrumentLayer *> _layers;
446 };
447
448
449 /**
450  * A textured layer of an instrument.
451  *
452  * This is a layer holding a single texture.  Normally, the texture's
453  * backgound should be transparent so that lower layers and the panel
454  * background can show through.
455  */
456 class FGTexturedLayer : public FGInstrumentLayer
457 {
458 public:
459   FGTexturedLayer (int w = -1, int h = -1) : FGInstrumentLayer(w, h) {}
460   FGTexturedLayer (const FGCroppedTexture &texture, int w = -1, int h = -1);
461   virtual ~FGTexturedLayer ();
462
463   virtual void draw ();
464
465   virtual void setTexture (const FGCroppedTexture &texture) {
466     _texture = texture;
467   }
468   virtual FGCroppedTexture &getTexture () { return _texture; }
469   virtual const FGCroppedTexture &getTexture () const { return _texture; }
470
471 private:
472   mutable FGCroppedTexture _texture;
473 };
474
475
476 /**
477  * A text layer of an instrument.
478  *
479  * This is a layer holding a string of static and/or generated text.
480  * It is useful for instruments that have text displays, such as
481  * a chronometer, GPS, or NavCom radio.
482  */
483 class FGTextLayer : public FGInstrumentLayer
484 {
485 public:
486   enum ChunkType {
487     TEXT,
488     TEXT_VALUE,
489     DOUBLE_VALUE
490   };
491
492   class Chunk : public SGConditional
493   {
494   public:
495     Chunk (const string &text, const string &fmt = "%s");
496     Chunk (ChunkType type, const SGPropertyNode * node,
497            const string &fmt = "", float mult = 1.0);
498
499     const char * getValue () const;
500   private:
501     ChunkType _type;
502     string _text;
503     const SGPropertyNode * _node;
504     string _fmt;
505     float _mult;
506     mutable char _buf[1024];
507   };
508
509   FGTextLayer (int w = -1, int h = -1);
510   virtual ~FGTextLayer ();
511
512   virtual void draw ();
513
514                                 // Transfer pointer!!
515   virtual void addChunk (Chunk * chunk);
516   virtual void setColor (float r, float g, float b);
517   virtual void setPointSize (float size);
518   virtual void setFontName ( const string &name );
519   virtual void setFont (fntFont * font);
520
521 private:
522
523   void recalc_value () const;
524
525   typedef vector<Chunk *> chunk_list;
526   chunk_list _chunks;
527   float _color[4];
528
529   float _pointSize;
530   mutable string _font_name;
531   mutable string _value;
532   mutable SGTimeStamp _then;
533   mutable SGTimeStamp _now;
534 };
535
536
537 /**
538  * A group layer that switches among its children.
539  *
540  * The first layer that passes its condition will be drawn, and
541  * any following layers will be ignored.
542  */
543 class FGSwitchLayer : public FGGroupLayer
544 {
545 public:
546                                 // Transfer pointers!!
547   FGSwitchLayer ();
548   virtual void draw ();
549
550 };
551
552
553
554 \f
555 ////////////////////////////////////////////////////////////////////////
556 // Functions.
557 ////////////////////////////////////////////////////////////////////////
558
559 /**
560  * Test whether the panel should be visible.
561  */
562 bool fgPanelVisible ();
563
564
565 \f
566 #endif // __PANEL_HXX
567
568 // end of panel.hxx
569
570
571